Gated sticky bit in fdiv with SpecialCase

This commit is contained in:
David Harris 2022-09-20 20:05:00 -07:00
parent 1cbdd20778
commit f7d272c315
5 changed files with 11 additions and 7 deletions

View File

@ -102,8 +102,8 @@
`define CORRSHIFTSZ ((`DIVRESLEN+`NF) > (3*`NF+8) ? (`DIVRESLEN+`NF) : (3*`NF+6)) `define CORRSHIFTSZ ((`DIVRESLEN+`NF) > (3*`NF+8) ? (`DIVRESLEN+`NF) : (3*`NF+6))
// division constants // division constants
`define RADIX 32'h2 `define RADIX 32'h4
`define DIVCOPIES 32'h1 `define DIVCOPIES 32'h3
`define DIVLEN ((`NF < `XLEN) ? (`XLEN) : (`NF + 3)) `define DIVLEN ((`NF < `XLEN) ? (`XLEN) : (`NF + 3))
// `define DIVN (`NF < `XLEN ? `XLEN : `NF+1) // length of input // `define DIVN (`NF < `XLEN ? `XLEN : `NF+1) // length of input
`define DIVN (`NF < `XLEN ? `XLEN : `NF+3) // length of input `define DIVN (`NF < `XLEN ? `XLEN : `NF+3) // length of input

View File

@ -61,6 +61,7 @@ module fdivsqrt(
logic [`DIVb+1:0] FirstC; logic [`DIVb+1:0] FirstC;
logic Firstun; logic Firstun;
logic WZero; logic WZero;
logic SpecialCase;
fdivsqrtpreproc fdivsqrtpreproc( fdivsqrtpreproc fdivsqrtpreproc(
.clk, .DivStart(DivStartE), .Xm(XmE), .QeM, .Xe(XeE), .Fmt(FmtE), .Ye(YeE), .clk, .DivStart(DivStartE), .Xm(XmE), .QeM, .Xe(XeE), .Fmt(FmtE), .Ye(YeE),
@ -69,11 +70,11 @@ module fdivsqrt(
.clk, .reset, .FmtE, .XsE, .SqrtE, .clk, .reset, .FmtE, .XsE, .SqrtE,
.DivBusy, .DivStart(DivStartE),.StallE, .StallM, .DivDone, .XZeroE, .YZeroE, .DivBusy, .DivStart(DivStartE),.StallE, .StallM, .DivDone, .XZeroE, .YZeroE,
.XNaNE, .YNaNE, .XNaNE, .YNaNE,
.XInfE, .YInfE, .WZero); .XInfE, .YInfE, .WZero, .SpecialCase);
fdivsqrtiter fdivsqrtiter( fdivsqrtiter fdivsqrtiter(
.clk, .Firstun, .D, .FirstU, .FirstUM, .FirstC, .SqrtE, .SqrtM, .clk, .Firstun, .D, .FirstU, .FirstUM, .FirstC, .SqrtE, .SqrtM,
.X,.Dpreproc, .FirstWS(WS), .FirstWC(WC), .NextWSN, .NextWCN, .X,.Dpreproc, .FirstWS(WS), .FirstWC(WC), .NextWSN, .NextWCN,
.DivStart(DivStartE), .Xe(XeE), .Ye(YeE), .XZeroE, .YZeroE, .DivStart(DivStartE), .Xe(XeE), .Ye(YeE), .XZeroE, .YZeroE,
.DivBusy); .DivBusy);
fdivsqrtpostproc fdivsqrtpostproc(.WS, .WC, .D, .FirstU, .FirstUM, .FirstC, .Firstun, .SqrtM, .QmM, .WZero, .DivSM); fdivsqrtpostproc fdivsqrtpostproc(.WS, .WC, .D, .FirstU, .FirstUM, .FirstC, .Firstun, .SqrtM, .SpecialCase, .QmM, .WZero, .DivSM);
endmodule endmodule

View File

@ -44,14 +44,14 @@ module fdivsqrtfsm(
input logic StallM, input logic StallM,
input logic WZero, input logic WZero,
output logic DivDone, output logic DivDone,
output logic DivBusy output logic DivBusy,
output logic SpecialCase
); );
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] step;
logic SpecialCase;
logic [`DURLEN-1:0] cycles; logic [`DURLEN-1:0] cycles;
// terminate immediately on special cases // terminate immediately on special cases

View File

@ -37,6 +37,7 @@ module fdivsqrtpostproc(
input logic [`DIVb+1:0] FirstC, input logic [`DIVb+1:0] FirstC,
input logic Firstun, input logic Firstun,
input logic SqrtM, input logic SqrtM,
input logic SpecialCase,
output logic [`DIVb:0] QmM, output logic [`DIVb:0] QmM,
output logic WZero, output logic WZero,
output logic DivSM output logic DivSM
@ -64,7 +65,7 @@ module fdivsqrtpostproc(
end else begin end else begin
assign WZero = weq0; assign WZero = weq0;
end end
assign DivSM = ~WZero; assign DivSM = ~WZero & ~(SpecialCase & SqrtM); // ***unsure why SpecialCaseM has to be gated by SqrtM, but otherwise fails regression on divide
// Determine if sticky bit is negative // Determine if sticky bit is negative
assign W = WC+WS; assign W = WC+WS;

View File

@ -128,10 +128,12 @@ module flags(
// | | | | | and if the input isnt infinity or NaN // | | | | | and if the input isnt infinity or NaN
// | | | | | | // | | | | | |
assign Underflow = ((FullRe[`NE+1] | (FullRe == 0) | ((FullRe == 1) & (Me == 0) & ~(UfPlus1&G)))&(R|S|G))&~(InfIn|NaNIn|DivByZero|Invalid); assign Underflow = ((FullRe[`NE+1] | (FullRe == 0) | ((FullRe == 1) & (Me == 0) & ~(UfPlus1&G)))&(R|S|G))&~(InfIn|NaNIn|DivByZero|Invalid);
//assign Underflow = ((FullRe[`NE+1] | (FullRe == 0) | ((FullRe == 1) & (Me == 0) & ~(UfPlus1&G)))&(R|S|G))&~(InfIn|NaNIn|DivByZero|Invalid|XZero);
// Set Inexact flag if the res is diffrent from what would be outputed given infinite precision // Set Inexact flag if the res is diffrent from what would be outputed given infinite precision
// - Don't set the underflow flag if an underflowed res isn't outputed // - Don't set the underflow flag if an underflowed res isn't outputed
assign FpInexact = (S|G|Overflow|R)&~(InfIn|NaNIn|DivByZero|Invalid); assign FpInexact = (S|G|Overflow|R)&~(InfIn|NaNIn|DivByZero|Invalid);
//assign FpInexact = (S|G|Overflow|R)&~(InfIn|NaNIn|DivByZero|Invalid|XZero);
// if the res is too small to be represented and not 0 // if the res is too small to be represented and not 0
// | and if the res is not invalid (outside the integer bounds) // | and if the res is not invalid (outside the integer bounds)