forked from Github_Repos/cvw
Renaming signals to match chapter
This commit is contained in:
parent
bde1c5eb1b
commit
1b4584e825
@ -32,7 +32,7 @@
|
||||
`define DESIGN_COMPILER 0
|
||||
|
||||
// RV32 or RV64: XLEN = 32 or 64
|
||||
`define XLEN 32
|
||||
`define XLEN 64
|
||||
|
||||
// IEEE 754 compliance
|
||||
`define IEEE754 0
|
||||
|
@ -11,7 +11,7 @@ module divshiftcalc(
|
||||
output logic [`NE+1:0] DivDenormShift
|
||||
);
|
||||
logic [`NE+1:0] NormShift;
|
||||
logic [`NE+1:0] Nf, NfPlus1;
|
||||
logic [`NE+1:0] Nf;
|
||||
|
||||
// is the result denromalized
|
||||
// if the exponent is 1 then the result needs to be normalized then the result is denormalizes
|
||||
@ -19,51 +19,25 @@ module divshiftcalc(
|
||||
// select the proper fraction lengnth
|
||||
if (`FPSIZES == 1) begin
|
||||
assign Nf = (`NE+2)'(`NF);
|
||||
assign NfPlus1 = (`NE+2)'(`NF+1);
|
||||
|
||||
end else if (`FPSIZES == 2) begin
|
||||
assign Nf = FmtM ? (`NE+2)'(`NF) : (`NE+2)'(`NF1);
|
||||
assign NfPlus1 = FmtM ? (`NE+2)'(`NF+1) : (`NE+2)'(`NF1+1);
|
||||
|
||||
end else if (`FPSIZES == 3) begin
|
||||
always_comb
|
||||
case (FmtM)
|
||||
`FMT: begin
|
||||
Nf = (`NE+2)'(`NF);
|
||||
NfPlus1 = (`NE+2)'(`NF+1);
|
||||
end
|
||||
`FMT1: begin
|
||||
Nf = (`NE+2)'(`NF1);
|
||||
NfPlus1 = (`NE+2)'(`NF1+1);
|
||||
end
|
||||
`FMT2: begin
|
||||
Nf = (`NE+2)'(`NF2);
|
||||
NfPlus1 = (`NE+2)'(`NF2+1);
|
||||
end
|
||||
default: begin
|
||||
Nf = 1'bx;
|
||||
NfPlus1 = 1'bx;
|
||||
end
|
||||
`FMT: Nf = (`NE+2)'(`NF);
|
||||
`FMT1: Nf = (`NE+2)'(`NF1);
|
||||
`FMT2: Nf = (`NE+2)'(`NF2);
|
||||
default: Nf = 1'bx;
|
||||
endcase
|
||||
end else if (`FPSIZES == 4) begin
|
||||
always_comb
|
||||
case (FmtM)
|
||||
2'h3: begin
|
||||
Nf = (`NE+2)'(`Q_NF);
|
||||
NfPlus1 = (`NE+2)'(`Q_NF+1);
|
||||
end
|
||||
2'h1: begin
|
||||
Nf = (`NE+2)'(`D_NF);
|
||||
NfPlus1 = (`NE+2)'(`D_NF+1);
|
||||
end
|
||||
2'h0: begin
|
||||
Nf = (`NE+2)'(`S_NF);
|
||||
NfPlus1 = (`NE+2)'(`S_NF+1);
|
||||
end
|
||||
2'h2: begin
|
||||
Nf = (`NE+2)'(`H_NF);
|
||||
NfPlus1 = (`NE+2)'(`H_NF+1);
|
||||
end
|
||||
2'h3: Nf = (`NE+2)'(`Q_NF);
|
||||
2'h1: Nf = (`NE+2)'(`D_NF);
|
||||
2'h0: Nf = (`NE+2)'(`S_NF);
|
||||
2'h2: Nf = (`NE+2)'(`H_NF);
|
||||
endcase
|
||||
end
|
||||
// if the result is denormalized
|
||||
|
@ -30,27 +30,27 @@
|
||||
`include "wally-config.vh"
|
||||
|
||||
module fma(
|
||||
input logic XSgnE, YSgnE, ZSgnE, // input's signs
|
||||
input logic [`NE-1:0] XExpE, YExpE, ZExpE, // biased exponents in B(NE.0) format
|
||||
input logic [`NF:0] XManE, YManE, ZManE, // fractions in U(0.NF) format
|
||||
input logic Xs, Ys, Zs, // input's signs
|
||||
input logic [`NE-1:0] Xe, Ye, Ze, // input's biased exponents in B(NE.0) format
|
||||
input logic [`NF:0] Xm, Ym, Zm, // input's significands in U(0.NF) format
|
||||
input logic XZeroE, YZeroE, ZZeroE, // is the input zero
|
||||
input logic [2:0] FOpCtrlE, // 000 = fmadd (X*Y)+Z, 001 = fmsub (X*Y)-Z, 010 = fnmsub -(X*Y)+Z, 011 = fnmadd -(X*Y)-Z, 100 = fmul (X*Y)
|
||||
input logic [`FMTBITS-1:0] FmtE, // precision 1 = double 0 = single
|
||||
output logic [`NE+1:0] ProdExpE, // X exponent + Y exponent - bias in B(NE+2.0) format; adds 2 bits to allow for size of number and negative sign
|
||||
output logic [`NE+1:0] Pe, // the product's exponent B(NE+2.0) format; adds 2 bits to allow for size of number and negative sign
|
||||
output logic AddendStickyE, // sticky bit that is calculated during alignment
|
||||
output logic KillProdE, // set the product to zero before addition if the product is too small to matter
|
||||
output logic [3*`NF+5:0] SumE, // the positive sum
|
||||
output logic [3*`NF+5:0] Sm, // the positive sum
|
||||
output logic NegSumE, // was the sum negitive
|
||||
output logic InvZE, // intert Z
|
||||
output logic InvA, // intert Z
|
||||
output logic ZSgnEffE, // the modified Z sign
|
||||
output logic PSgnE, // the product's sign
|
||||
output logic Ps, // the product's sign
|
||||
output logic [$clog2(3*`NF+7)-1:0] FmaNormCntE // normalization shift cnt
|
||||
);
|
||||
|
||||
logic [2*`NF+1:0] ProdManE; // 1.X frac * 1.Y frac in U(2.2Nf) format
|
||||
logic [3*`NF+5:0] AlignedAddendE; // Z aligned for addition in U(NF+5.2NF+1)
|
||||
logic [3*`NF+6:0] AlignedAddendInv; // aligned addend possibly inverted
|
||||
logic [2*`NF+1:0] ProdManKilled; // the product's mantissa possibly killed
|
||||
logic [2*`NF+1:0] Pm; // the product's significand in U(2.2Nf) format
|
||||
logic [3*`NF+5:0] Am; // Z aligned for addition in U(NF+5.2NF+1)
|
||||
logic [3*`NF+6:0] AmInv; // aligned addend possibly inverted
|
||||
logic [2*`NF+1:0] PmKilled; // the product's mantissa possibly killed
|
||||
logic [3*`NF+6:0] PreSum, NegPreSum; // positive and negitve versions of the sum
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Calculate the product
|
||||
@ -62,43 +62,40 @@ module fma(
|
||||
|
||||
|
||||
// calculate the product's exponent
|
||||
expadd expadd(.FmtE, .XExpE, .YExpE, .XZeroE, .YZeroE, .ProdExpE);
|
||||
expadd expadd(.FmtE, .Xe, .Ye, .XZeroE, .YZeroE, .Pe);
|
||||
|
||||
// multiplication of the mantissa's
|
||||
mult mult(.XManE, .YManE, .ProdManE);
|
||||
mult mult(.Xm, .Ym, .Pm);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Alignment shifter
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
align align(.ZExpE, .ZManE, .XZeroE, .YZeroE, .ZZeroE, .XExpE, .YExpE,
|
||||
.AlignedAddendE, .AddendStickyE, .KillProdE);
|
||||
align align(.Ze, .Zm, .XZeroE, .YZeroE, .ZZeroE, .Xe, .Ye,
|
||||
.Am, .AddendStickyE, .KillProdE);
|
||||
|
||||
// calculate the signs and take the opperation into account
|
||||
sign sign(.FOpCtrlE, .XSgnE, .YSgnE, .ZSgnE, .PSgnE, .ZSgnEffE);
|
||||
sign sign(.FOpCtrlE, .Xs, .Ys, .Zs, .Ps, .ZSgnEffE);
|
||||
|
||||
// ///////////////////////////////////////////////////////////////////////////////
|
||||
// // Addition/LZA
|
||||
// ///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
add add(.AlignedAddendE, .ProdManE, .PSgnE, .ZSgnEffE, .KillProdE, .AlignedAddendInv, .ProdManKilled, .NegSumE, .PreSum, .NegPreSum, .InvZE, .XZeroE, .YZeroE);
|
||||
add add(.Am, .Pm, .Ps, .ZSgnEffE, .KillProdE, .AmInv, .PmKilled, .NegSumE, .PreSum, .NegPreSum, .InvA, .XZeroE, .YZeroE, .Sm);
|
||||
|
||||
loa loa(.A(AlignedAddendInv+{(3*`NF+6)'(0),InvZE}), .P(ProdManKilled), .FmaNormCntE);
|
||||
|
||||
// Choose the positive sum and accompanying LZA result.
|
||||
assign SumE = NegSumE ? NegPreSum[3*`NF+5:0] : PreSum[3*`NF+5:0];
|
||||
loa loa(.A(AmInv+{(3*`NF+6)'(0),InvA}), .P(PmKilled), .FmaNormCntE);
|
||||
endmodule
|
||||
|
||||
|
||||
module expadd(
|
||||
input logic [`FMTBITS-1:0] FmtE, // precision
|
||||
input logic [`NE-1:0] XExpE, YExpE, // input exponents
|
||||
input logic [`NE-1:0] Xe, Ye, // input exponents
|
||||
input logic XZeroE, YZeroE, // are the inputs zero
|
||||
output logic [`NE+1:0] ProdExpE // product's exponent B^(1023)NE+2
|
||||
output logic [`NE+1:0] Pe // product's exponent B^(1023)NE+2
|
||||
);
|
||||
|
||||
// kill the exponent if the product is zero - either X or Y is 0
|
||||
assign ProdExpE = ({2'b0, XExpE} + {2'b0, YExpE} - {2'b0, (`NE)'(`BIAS)})&{`NE+2{~(XZeroE|YZeroE)}};
|
||||
assign Pe = ({2'b0, Xe} + {2'b0, Ye} - {2'b0, (`NE)'(`BIAS)})&{`NE+2{~(XZeroE|YZeroE)}};
|
||||
|
||||
endmodule
|
||||
|
||||
@ -107,10 +104,10 @@ endmodule
|
||||
|
||||
|
||||
module mult(
|
||||
input logic [`NF:0] XManE, YManE,
|
||||
output logic [2*`NF+1:0] ProdManE
|
||||
input logic [`NF:0] Xm, Ym,
|
||||
output logic [2*`NF+1:0] Pm
|
||||
);
|
||||
assign ProdManE = XManE * YManE;
|
||||
assign Pm = Xm * Ym;
|
||||
endmodule
|
||||
|
||||
|
||||
@ -122,8 +119,8 @@ endmodule
|
||||
|
||||
module sign(
|
||||
input logic [2:0] FOpCtrlE, // precision
|
||||
input logic XSgnE, YSgnE, ZSgnE, // are the inputs denormalized
|
||||
output logic PSgnE, // the product's sign - takes opperation into account
|
||||
input logic Xs, Ys, Zs, // are the inputs denormalized
|
||||
output logic Ps, // the product's sign - takes opperation into account
|
||||
output logic ZSgnEffE // Z sign used in fma - takes opperation into account
|
||||
);
|
||||
|
||||
@ -131,9 +128,9 @@ module sign(
|
||||
// Negate product's sign if FNMADD or FNMSUB
|
||||
|
||||
// flip is negation opperation
|
||||
assign PSgnE = XSgnE ^ YSgnE ^ (FOpCtrlE[1]&~FOpCtrlE[2]);
|
||||
assign Ps = Xs ^ Ys ^ (FOpCtrlE[1]&~FOpCtrlE[2]);
|
||||
// flip if subtraction
|
||||
assign ZSgnEffE = ZSgnE^FOpCtrlE[0];
|
||||
assign ZSgnEffE = Zs^FOpCtrlE[0];
|
||||
|
||||
endmodule
|
||||
|
||||
@ -145,10 +142,10 @@ endmodule
|
||||
|
||||
|
||||
module align(
|
||||
input logic [`NE-1:0] XExpE, YExpE, ZExpE, // biased exponents in B(NE.0) format
|
||||
input logic [`NF:0] ZManE, // fractions in U(0.NF) format]
|
||||
input logic [`NE-1:0] Xe, Ye, Ze, // biased exponents in B(NE.0) format
|
||||
input logic [`NF:0] Zm, // fractions in U(0.NF) format]
|
||||
input logic XZeroE, YZeroE, ZZeroE, // is the input zero
|
||||
output logic [3*`NF+5:0] AlignedAddendE, // Z aligned for addition in U(NF+5.2NF+1)
|
||||
output logic [3*`NF+5:0] Am, // Z aligned for addition in U(NF+5.2NF+1)
|
||||
output logic AddendStickyE, // Sticky bit calculated from the aliged addend
|
||||
output logic KillProdE // should the product be set to zero
|
||||
);
|
||||
@ -156,6 +153,7 @@ module align(
|
||||
logic [`NE+1:0] AlignCnt; // how far to shift the addend to align with the product in Q(NE+2.0) format
|
||||
logic [4*`NF+5:0] ZManShifted; // output of the alignment shifter including sticky bits U(NF+5.3NF+1)
|
||||
logic [4*`NF+5:0] ZManPreShifted; // input to the alignment shifter U(NF+5.3NF+1)
|
||||
logic KillZ;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Alignment shifter
|
||||
@ -164,15 +162,19 @@ module align(
|
||||
// determine the shift count for alignment
|
||||
// - negitive means Z is larger, so shift Z left
|
||||
// - positive means the product is larger, so shift Z right
|
||||
// This could have been done using ProdExpE, but AlignCnt is on the critical path so we replicate logic for speed
|
||||
assign AlignCnt = XZeroE|YZeroE ? -(`NE+2)'($unsigned(1)) : {2'b0, XExpE} + {2'b0, YExpE} - {2'b0, (`NE)'(`BIAS)} + (`NE+2)'(`NF)+3 - {2'b0, ZExpE};
|
||||
// This could have been done using Pe, but AlignCnt is on the critical path so we replicate logic for speed
|
||||
assign AlignCnt = {2'b0, Xe} + {2'b0, Ye} - {2'b0, (`NE)'(`BIAS)} + (`NE+2)'(`NF+3) - {2'b0, Ze};
|
||||
|
||||
// Defualt Addition without shifting
|
||||
// | 54'b0 | 106'b(product) | 2'b0 |
|
||||
// | addnend |
|
||||
|
||||
// the 1'b0 before the added is because the product's mantissa has two bits before the binary point (xx.xxxxxxxxxx...)
|
||||
assign ZManPreShifted = {ZManE,(3*`NF+5)'(0)};
|
||||
assign ZManPreShifted = {Zm,(3*`NF+5)'(0)};
|
||||
|
||||
assign KillProdE = AlignCnt[`NE+1]|XZeroE|YZeroE;
|
||||
assign KillZ = $signed(AlignCnt)>$signed((`NE+2)'(3)*(`NE+2)'(`NF)+(`NE+2)'(5));
|
||||
|
||||
always_comb
|
||||
begin
|
||||
|
||||
@ -180,34 +182,31 @@ module align(
|
||||
|
||||
// | 54'b0 | 106'b(product) | 2'b0 |
|
||||
// | addnend |
|
||||
if ($signed(AlignCnt) < $signed((`NE+2)'(0))) begin
|
||||
KillProdE = 1;
|
||||
if (KillProdE) begin
|
||||
ZManShifted = ZManPreShifted;
|
||||
AddendStickyE = ~(XZeroE|YZeroE);
|
||||
|
||||
// If the Addend is shifted right
|
||||
// | 54'b0 | 106'b(product) | 2'b0 |
|
||||
// | addnend |
|
||||
end else if ($signed(AlignCnt)<=$signed((`NE+2)'(3)*(`NE+2)'(`NF)+(`NE+2)'(5))) begin
|
||||
KillProdE = 0;
|
||||
ZManShifted = ZManPreShifted >> AlignCnt;
|
||||
AddendStickyE = |(ZManShifted[`NF-1:0]);
|
||||
|
||||
// If the addend is too small to effect the addition
|
||||
// - The addend has to shift two past the end of the addend to be considered too small
|
||||
// - The 2 extra bits are needed for rounding
|
||||
|
||||
// | 54'b0 | 106'b(product) | 2'b0 |
|
||||
// | addnend |
|
||||
end else begin
|
||||
KillProdE = 0;
|
||||
end else if (KillZ) begin
|
||||
ZManShifted = 0;
|
||||
AddendStickyE = ~ZZeroE;
|
||||
|
||||
// If the Addend is shifted right
|
||||
// | 54'b0 | 106'b(product) | 2'b0 |
|
||||
// | addnend |
|
||||
end else begin
|
||||
ZManShifted = ZManPreShifted >> AlignCnt;
|
||||
AddendStickyE = |(ZManShifted[`NF-1:0]);
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
assign AlignedAddendE = ZManShifted[4*`NF+5:`NF];
|
||||
assign Am = ZManShifted[4*`NF+5:`NF];
|
||||
|
||||
endmodule
|
||||
|
||||
@ -218,15 +217,16 @@ endmodule
|
||||
|
||||
|
||||
module add(
|
||||
input logic [3*`NF+5:0] AlignedAddendE, // Z aligned for addition in U(NF+5.2NF+1)
|
||||
input logic [2*`NF+1:0] ProdManE, // the product's mantissa
|
||||
input logic PSgnE, ZSgnEffE,// the product and modified Z signs
|
||||
input logic [3*`NF+5:0] Am, // Z aligned for addition in U(NF+5.2NF+1)
|
||||
input logic [2*`NF+1:0] Pm, // the product's mantissa
|
||||
input logic Ps, ZSgnEffE,// the product and modified Z signs
|
||||
input logic KillProdE, // should the product be set to 0
|
||||
input logic XZeroE, YZeroE, // is the input zero
|
||||
output logic [3*`NF+6:0] AlignedAddendInv, // aligned addend possibly inverted
|
||||
output logic [2*`NF+1:0] ProdManKilled, // the product's mantissa possibly killed
|
||||
output logic [3*`NF+6:0] AmInv, // aligned addend possibly inverted
|
||||
output logic [2*`NF+1:0] PmKilled, // the product's mantissa possibly killed
|
||||
output logic NegSumE, // was the sum negitive
|
||||
output logic InvZE, // do you invert Z
|
||||
output logic InvA, // do you invert Z
|
||||
output logic [3*`NF+5:0] Sm, // the positive sum
|
||||
output logic [3*`NF+6:0] PreSum, NegPreSum// possibly negitive sum
|
||||
);
|
||||
|
||||
@ -237,23 +237,25 @@ module add(
|
||||
// Negate Z when doing one of the following opperations:
|
||||
// -prod + Z
|
||||
// prod - Z
|
||||
assign InvZE = ZSgnEffE ^ PSgnE;
|
||||
assign InvA = ZSgnEffE ^ Ps;
|
||||
|
||||
// Choose an inverted or non-inverted addend - the one has to be added now for the LZA
|
||||
assign AlignedAddendInv = InvZE ? {1'b1, ~AlignedAddendE} : {1'b0, AlignedAddendE};
|
||||
assign AmInv = InvA ? {1'b1, ~Am} : {1'b0, Am};
|
||||
// Kill the product if the product is too small to effect the addition (determined in fma1.sv)
|
||||
assign ProdManKilled = ProdManE&{2*`NF+2{~KillProdE}};
|
||||
assign PmKilled = Pm&{2*`NF+2{~KillProdE}};
|
||||
|
||||
|
||||
|
||||
// Do the addition
|
||||
// - calculate a positive and negitive sum in parallel
|
||||
assign PreSum = AlignedAddendInv + {{`NF+3{1'b0}}, ProdManKilled, 2'b0} + {{3*`NF+6{1'b0}}, InvZE};
|
||||
assign NegPreSum = XZeroE|YZeroE|KillProdE ? {1'b0, AlignedAddendE} : {1'b0, AlignedAddendE} + {{`NF+3{1'b1}}, ~ProdManKilled, 2'b0} + {(3*`NF+7)'(4)};
|
||||
assign PreSum = {{`NF+3{1'b0}}, PmKilled, 2'b0} + AmInv + {{3*`NF+6{1'b0}}, InvA};
|
||||
assign NegPreSum = {1'b0, Am} + {{`NF+3{1'b1}}, ~PmKilled, 2'b0} + {(3*`NF+7)'(4)};
|
||||
|
||||
// Is the sum negitive
|
||||
assign NegSumE = PreSum[3*`NF+6];
|
||||
|
||||
// Choose the positive sum and accompanying LZA result.
|
||||
assign Sm = NegSumE ? NegPreSum[3*`NF+5:0] : PreSum[3*`NF+5:0];
|
||||
endmodule
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ module fmashiftcalc(
|
||||
// calculate the sum's exponent
|
||||
assign NormSumExp = KillProdM ? {2'b0, ZExpM[`NE-1:1], ZExpM[0]&~ZDenormM} : ProdExpM + -{{`NE+2-$unsigned($clog2(3*`NF+7)){1'b0}}, FmaNormCntM} - 1 + (`NE+2)'(`NF+4);
|
||||
|
||||
//convert the sum's exponent into the propper percision
|
||||
//convert the sum's exponent into the proper percision
|
||||
if (`FPSIZES == 1) begin
|
||||
assign ConvNormSumExp = NormSumExp;
|
||||
|
||||
@ -105,7 +105,7 @@ module fmashiftcalc(
|
||||
2'h1: PreResultDenorm = Sum1LEZ & Sum1GEFL & ~SumZero;
|
||||
2'h0: PreResultDenorm = Sum2LEZ & Sum2GEFL & ~SumZero;
|
||||
2'h2: PreResultDenorm = Sum3LEZ & Sum3GEFL & ~SumZero;
|
||||
endcase
|
||||
endcase // *** remove checking to see if it's underflowed and only check for less than zero for denorm checking
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -110,7 +110,7 @@ module fpu (
|
||||
logic [`NE+1:0] ProdExpE, ProdExpM;
|
||||
logic AddendStickyE, AddendStickyM;
|
||||
logic KillProdE, KillProdM;
|
||||
logic InvZE, InvZM;
|
||||
logic InvAE, InvAM;
|
||||
logic NegSumE, NegSumM;
|
||||
logic ZSgnEffE, ZSgnEffM;
|
||||
logic PSgnE, PSgnM;
|
||||
@ -249,10 +249,10 @@ module fpu (
|
||||
.XZeroE, .YZeroE, .ZZeroE, .XInfE, .YInfE, .ZInfE, .XExpMaxE);
|
||||
|
||||
// fma - does multiply, add, and multiply-add instructions
|
||||
fma fma (.XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE,
|
||||
.XManE, .YManE, .ZManE, .XZeroE, .YZeroE, .ZZeroE,
|
||||
.FOpCtrlE, .FmtE, .SumE, .NegSumE, .InvZE, .FmaNormCntE,
|
||||
.ZSgnEffE, .PSgnE, .ProdExpE, .AddendStickyE, .KillProdE);
|
||||
fma fma (.Xs(XSgnE), .Ys(YSgnE), .Zs(ZSgnE), .Xe(XExpE), .Ye(YExpE), .Ze(ZExpE),
|
||||
.Xm(XManE), .Ym(YManE), .Zm(ZManE), .XZeroE, .YZeroE, .ZZeroE,
|
||||
.FOpCtrlE, .FmtE, .Sm(SumE), .NegSumE, .InvA(InvAE), .FmaNormCntE,
|
||||
.ZSgnEffE, .Ps(PSgnE), .Pe(ProdExpE), .AddendStickyE, .KillProdE);
|
||||
|
||||
// fpdivsqrt using Goldschmidt's iteration
|
||||
if(`FLEN == 64) begin
|
||||
@ -351,8 +351,8 @@ module fpu (
|
||||
flopenrc #(3*`NF+6) EMRegFma2(clk, reset, FlushM, ~StallM, SumE, SumM);
|
||||
flopenrc #(`NE+2) EMRegFma3(clk, reset, FlushM, ~StallM, ProdExpE, ProdExpM);
|
||||
flopenrc #($clog2(3*`NF+7)+6) EMRegFma4(clk, reset, FlushM, ~StallM,
|
||||
{AddendStickyE, KillProdE, InvZE, FmaNormCntE, NegSumE, ZSgnEffE, PSgnE},
|
||||
{AddendStickyM, KillProdM, InvZM, FmaNormCntM, NegSumM, ZSgnEffM, PSgnM});
|
||||
{AddendStickyE, KillProdE, InvAE, FmaNormCntE, NegSumE, ZSgnEffE, PSgnE},
|
||||
{AddendStickyM, KillProdM, InvAM, FmaNormCntM, NegSumM, ZSgnEffM, PSgnM});
|
||||
flopenrc #(`NE+`LOGCVTLEN+`CVTLEN+4) EMRegCvt(clk, reset, FlushM, ~StallM,
|
||||
{CvtCalcExpE, CvtShiftAmtE, CvtResDenormUfE, CvtResSgnE, IntZeroE, CvtLzcInE},
|
||||
{CvtCalcExpM, CvtShiftAmtM, CvtResDenormUfM, CvtResSgnM, IntZeroM, CvtLzcInM});
|
||||
@ -374,7 +374,7 @@ module fpu (
|
||||
postprocess postprocess(.XSgnM, .YSgnM, .ZExpM, .XManM, .YManM, .ZManM, .FrmM, .FmtM, .ProdExpM, .EarlyTermShiftDiv2M,
|
||||
.AddendStickyM, .KillProdM, .XZeroM, .YZeroM, .ZZeroM, .XInfM, .YInfM, .Quot,
|
||||
.ZInfM, .XNaNM, .YNaNM, .ZNaNM, .XSNaNM, .YSNaNM, .ZSNaNM, .SumM, .DivCalcExpM,
|
||||
.NegSumM, .InvZM, .ZDenormM, .ZSgnEffM, .PSgnM, .FOpCtrlM, .FmaNormCntM, .DivNegStickyM,
|
||||
.NegSumM, .InvZM(InvAM), .ZDenormM, .ZSgnEffM, .PSgnM, .FOpCtrlM, .FmaNormCntM, .DivNegStickyM,
|
||||
.CvtCalcExpM, .CvtResDenormUfM,.CvtShiftAmtM, .CvtResSgnM, .FWriteIntM, .DivStickyM,
|
||||
.CvtLzcInM, .IntZeroM, .PostProcSelM, .PostProcResM, .PostProcFlgM, .FCvtIntResM);
|
||||
|
||||
|
@ -109,6 +109,7 @@ module postprocess(
|
||||
// conversion signals
|
||||
logic [`CVTLEN+`NF:0] CvtShiftIn; // number to be shifted
|
||||
logic [1:0] NegResMSBS;
|
||||
logic [`XLEN+1:0] NegRes;
|
||||
logic CvtResUf;
|
||||
// readability signals
|
||||
logic Mult; // multiply opperation
|
||||
@ -166,7 +167,7 @@ module postprocess(
|
||||
ShiftAmt = {{$clog2(`NORMSHIFTSZ)-$clog2(`CVTLEN+1){1'b0}}, CvtShiftAmtM};
|
||||
ShiftIn = {CvtShiftIn, {`NORMSHIFTSZ-`CVTLEN-`NF-1{1'b0}}};
|
||||
end
|
||||
2'b01: begin //div ***prob can take out
|
||||
2'b01: begin //div
|
||||
ShiftAmt = DivShiftAmt;
|
||||
ShiftIn = DivShiftIn;
|
||||
end
|
||||
@ -201,9 +202,11 @@ module postprocess(
|
||||
// Sign calculation
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
resultsign resultsign(.FrmM, .PSgnM, .ZSgnEffM, .InvZM, .SumExp, .Round, .Sticky,
|
||||
.FmaOp, .DivOp, .CvtOp, .ZInfM, .InfIn, .NegSumM, .SumZero, .Mult,
|
||||
.XSgnM, .YSgnM, .CvtResSgnM, .RoundSgn, .ResSgn);
|
||||
resultsign resultsign(.FrmM, .PSgnM, .ZSgnEffM, .SumExp, .Round, .Sticky,
|
||||
.FmaOp, .ZInfM, .InfIn, .SumZero, .Mult, .RoundSgn, .ResSgn);
|
||||
|
||||
roundsign roundsign(.PSgnM, .ZSgnEffM, .InvZM, .FmaOp, .DivOp, .CvtOp, .NegSumM,
|
||||
.XSgnM, .YSgnM, .CvtResSgnM, .RoundSgn);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Flags
|
||||
@ -219,10 +222,11 @@ module postprocess(
|
||||
// Select the result
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
resultselect resultselect(.XSgnM, .ZExpM, .XManM, .YManM, .ZManM, .ZDenormM, .ZZeroM, .XZeroM, .IntInvalid,
|
||||
.IntZeroM, .FrmM, .OutFmt, .AddendStickyM, .KillProdM, .XNaNM, .YNaNM, .ZNaNM, .RoundAdd, .CvtResUf,
|
||||
.NaNIn, .IntToFp, .Int64, .Signed, .CvtOp, .FmaOp, .Plus1, .Invalid, .Overflow, .InfIn, .NegResMSBS,
|
||||
negateintres negateintres(.XSgnM, .Shifted, .Signed, .Int64, .Plus1, .NegResMSBS, .NegRes);
|
||||
resultselect resultselect(.XSgnM, .XManM, .YManM, .ZManM, .XZeroM, .IntInvalid,
|
||||
.IntZeroM, .FrmM, .OutFmt, .XNaNM, .YNaNM, .ZNaNM, .CvtResUf,
|
||||
.NaNIn, .IntToFp, .Int64, .Signed, .CvtOp, .FmaOp, .Plus1, .Invalid, .Overflow, .InfIn, .NegRes,
|
||||
.XInfM, .YInfM, .DivOp,
|
||||
.DivByZero, .FullResExp, .Shifted, .CvtCalcExpM, .ResSgn, .ResExp, .ResFrac, .PostProcResM, .FCvtIntResM);
|
||||
.DivByZero, .FullResExp, .CvtCalcExpM, .ResSgn, .ResExp, .ResFrac, .PostProcResM, .FCvtIntResM);
|
||||
|
||||
endmodule
|
||||
|
@ -1,45 +1,38 @@
|
||||
`include "wally-config.vh"
|
||||
|
||||
module resultselect(
|
||||
input logic XSgnM, // input signs
|
||||
input logic [`NE-1:0] ZExpM, // input exponents
|
||||
input logic [`NF:0] XManM, YManM, ZManM, // input mantissas
|
||||
input logic XNaNM, YNaNM, ZNaNM, // inputs are NaN
|
||||
input logic [2:0] FrmM, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude
|
||||
input logic [`FMTBITS-1:0] OutFmt, // output format
|
||||
input logic InfIn,
|
||||
input logic XInfM, YInfM,
|
||||
input logic XZeroM, ZZeroM,
|
||||
input logic IntZeroM,
|
||||
input logic NaNIn,
|
||||
input logic IntToFp,
|
||||
input logic Int64,
|
||||
input logic Signed,
|
||||
input logic CvtOp,
|
||||
input logic DivOp,
|
||||
input logic FmaOp,
|
||||
input logic [`NORMSHIFTSZ-1:0] Shifted, // is the sum zero
|
||||
input logic Plus1,
|
||||
input logic DivByZero,
|
||||
input logic [`NE:0] CvtCalcExpM, // the calculated expoent
|
||||
input logic AddendStickyM, // sticky bit that is calculated during alignment
|
||||
input logic KillProdM, // set the product to zero before addition if the product is too small to matter
|
||||
input logic ZDenormM, // is the original precision denormalized
|
||||
input logic ResSgn, // the res's sign
|
||||
input logic [`FLEN:0] RoundAdd, // how much to add to the res
|
||||
input logic IntInvalid, Invalid, Overflow, // flags
|
||||
input logic CvtResUf,
|
||||
input logic [`NE-1:0] ResExp, // Res exponent
|
||||
input logic [`NE+1:0] FullResExp, // Res exponent
|
||||
input logic [`NF-1:0] ResFrac, // Res fraction
|
||||
output logic [`FLEN-1:0] PostProcResM, // final res
|
||||
output logic [1:0] NegResMSBS,
|
||||
output logic [`XLEN-1:0] FCvtIntResM // final res
|
||||
input logic XSgnM, // input signs
|
||||
input logic [`NF:0] XManM, YManM, ZManM, // input mantissas
|
||||
input logic XNaNM, YNaNM, ZNaNM, // inputs are NaN
|
||||
input logic [2:0] FrmM, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude
|
||||
input logic [`FMTBITS-1:0] OutFmt, // output format
|
||||
input logic InfIn,
|
||||
input logic XInfM, YInfM,
|
||||
input logic XZeroM,
|
||||
input logic IntZeroM,
|
||||
input logic NaNIn,
|
||||
input logic IntToFp,
|
||||
input logic Int64,
|
||||
input logic Signed,
|
||||
input logic CvtOp,
|
||||
input logic DivOp,
|
||||
input logic FmaOp,
|
||||
input logic Plus1,
|
||||
input logic DivByZero,
|
||||
input logic [`NE:0] CvtCalcExpM, // the calculated expoent
|
||||
input logic ResSgn, // the res's sign
|
||||
input logic IntInvalid, Invalid, Overflow, // flags
|
||||
input logic CvtResUf,
|
||||
input logic [`NE-1:0] ResExp, // Res exponent
|
||||
input logic [`NE+1:0] FullResExp, // Res exponent
|
||||
input logic [`NF-1:0] ResFrac, // Res fraction
|
||||
input logic [`XLEN+1:0] NegRes, // the negation of the result
|
||||
output logic [`FLEN-1:0] PostProcResM, // final res
|
||||
output logic [`XLEN-1:0] FCvtIntResM // final res
|
||||
);
|
||||
logic [`FLEN-1:0] XNaNRes, YNaNRes, ZNaNRes, InvalidRes, OfRes, UfRes, NormRes; // possible results
|
||||
logic OfResMax;
|
||||
logic [`XLEN-1:0] OfIntRes; // the overflow result for integer output
|
||||
logic [`XLEN+1:0] NegRes; // the negation of the result
|
||||
logic KillRes;
|
||||
logic SelOfRes;
|
||||
|
||||
@ -254,13 +247,7 @@ module resultselect(
|
||||
Int64 ? {1'b0, {`XLEN-1{1'b1}}} : {{`XLEN-32{1'b0}}, 1'b0, {31{1'b1}}} : // signed positive
|
||||
XSgnM&~XNaNM ? {`XLEN{1'b0}} : // unsigned negitive
|
||||
{`XLEN{1'b1}};// unsigned positive
|
||||
|
||||
// round and negate the positive res if needed
|
||||
assign NegRes = XSgnM ? -({2'b0, Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`XLEN]}+{{`XLEN+1{1'b0}}, Plus1}) : {2'b0, Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`XLEN]}+{{`XLEN+1{1'b0}}, Plus1};
|
||||
|
||||
//*** false critical path probably
|
||||
assign NegResMSBS = Signed ? Int64 ? NegRes[`XLEN:`XLEN-1] : NegRes[32:31] :
|
||||
Int64 ? NegRes[`XLEN+1:`XLEN] : NegRes[33:32];
|
||||
|
||||
|
||||
// select the integer output
|
||||
// - if the input is invalid (out of bounds NaN or Inf) then output overflow res
|
||||
|
@ -3,31 +3,21 @@
|
||||
module resultsign(
|
||||
input logic [2:0] FrmM,
|
||||
input logic PSgnM, ZSgnEffM,
|
||||
input logic InvZM,
|
||||
input logic XSgnM,
|
||||
input logic YSgnM,
|
||||
input logic ZInfM,
|
||||
input logic InfIn,
|
||||
input logic NegSumM,
|
||||
input logic FmaOp,
|
||||
input logic DivOp,
|
||||
input logic CvtOp,
|
||||
input logic [`NE+1:0] SumExp,
|
||||
input logic SumZero,
|
||||
input logic Mult,
|
||||
input logic Round,
|
||||
input logic Sticky,
|
||||
input logic CvtResSgnM,
|
||||
output logic RoundSgn,
|
||||
input logic RoundSgn,
|
||||
output logic ResSgn
|
||||
);
|
||||
|
||||
logic ZeroSgn;
|
||||
logic InfSgn;
|
||||
logic FmaResSgn;
|
||||
logic FmaResSgnTmp;
|
||||
logic Underflow;
|
||||
logic DivSgn;
|
||||
// logic ResultSgnTmp;
|
||||
|
||||
// Determine the sign if the sum is zero
|
||||
@ -42,14 +32,7 @@ module resultsign(
|
||||
// if p - z is the Sum negitive
|
||||
// if -p + z is the Sum positive
|
||||
// if -p - z then the Sum is negitive
|
||||
assign FmaResSgnTmp = InvZM&(ZSgnEffM)&NegSumM | InvZM&PSgnM&~NegSumM | (ZSgnEffM&PSgnM);
|
||||
assign InfSgn = ZInfM ? ZSgnEffM : PSgnM;
|
||||
assign FmaResSgn = InfIn ? InfSgn : SumZero ? ZeroSgn : FmaResSgnTmp;
|
||||
|
||||
assign DivSgn = XSgnM^YSgnM;
|
||||
|
||||
// Sign for rounding calulation
|
||||
assign RoundSgn = (FmaResSgnTmp&FmaOp) | (CvtResSgnM&CvtOp) | (DivSgn&DivOp);
|
||||
assign ResSgn = (FmaResSgn&FmaOp) | (CvtResSgnM&CvtOp) | (DivSgn&DivOp);
|
||||
assign ResSgn = InfIn&FmaOp ? InfSgn : SumZero&FmaOp ? ZeroSgn : RoundSgn;
|
||||
|
||||
endmodule
|
@ -61,15 +61,15 @@ module testbenchfp;
|
||||
|
||||
// in-between FMA signals
|
||||
logic Mult;
|
||||
logic [`NE+1:0] ProdExpE;
|
||||
logic [`NE+1:0] Pe;
|
||||
logic AddendStickyE;
|
||||
logic KillProdE;
|
||||
logic [$clog2(3*`NF+7)-1:0] FmaNormCntE;
|
||||
logic [3*`NF+5:0] SumE;
|
||||
logic [3*`NF+5:0] Sm;
|
||||
logic InvZE;
|
||||
logic NegSumE;
|
||||
logic ZSgnEffE;
|
||||
logic PSgnE;
|
||||
logic Ps;
|
||||
logic DivSticky;
|
||||
logic DivNegSticky;
|
||||
logic [`NE+1:0] DivCalcExp;
|
||||
@ -637,12 +637,12 @@ module testbenchfp;
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// instantiate devices under test
|
||||
fma fma(.XSgnE(XSgn), .YSgnE(YSgn), .ZSgnE(ZSgn),
|
||||
.XExpE(XExp), .YExpE(YExp), .ZExpE(ZExp),
|
||||
.XManE(XMan), .YManE(YMan), .ZManE(ZMan),
|
||||
fma fma(.Xs(XSgn), .Ys(YSgn), .Zs(ZSgn),
|
||||
.Xe(XExp), .Ye(YExp), .Ze(ZExp),
|
||||
.Xm(XMan), .Ym(YMan), .Zm(ZMan),
|
||||
.XZeroE(XZero), .YZeroE(YZero), .ZZeroE(ZZero),
|
||||
.FOpCtrlE(OpCtrlVal), .FmtE(ModFmt), .SumE, .NegSumE, .InvZE, .FmaNormCntE, .ZSgnEffE, .PSgnE,
|
||||
.ProdExpE, .AddendStickyE, .KillProdE);
|
||||
.FOpCtrlE(OpCtrlVal), .FmtE(ModFmt), .Sm, .NegSumE, .InvZE, .FmaNormCntE, .ZSgnEffE, .Ps,
|
||||
.Pe, .AddendStickyE, .KillProdE);
|
||||
|
||||
postprocess postprocess(.XSgnM(XSgn), .YSgnM(YSgn), .PostProcSelM(UnitVal[1:0]),
|
||||
.ZExpM(ZExp), .ZDenormM(ZDenorm), .FOpCtrlM(OpCtrlVal), .Quot, .DivCalcExpM(DivCalcExp),
|
||||
@ -651,8 +651,8 @@ module testbenchfp;
|
||||
.XZeroM(XZero), .YZeroM(YZero), .ZZeroM(ZZero), .CvtShiftAmtM(CvtShiftAmtE),
|
||||
.XInfM(XInf), .YInfM(YInf), .ZInfM(ZInf), .CvtResSgnM(CvtResSgnE), .FWriteIntM(WriteIntVal),
|
||||
.XSNaNM(XSNaN), .YSNaNM(YSNaN), .ZSNaNM(ZSNaN), .CvtLzcInM(CvtLzcInE), .IntZeroM(IntZeroE),
|
||||
.KillProdM(KillProdE), .AddendStickyM(AddendStickyE), .ProdExpM(ProdExpE),
|
||||
.SumM(SumE), .NegSumM(NegSumE), .InvZM(InvZE), .FmaNormCntM(FmaNormCntE), .EarlyTermShiftDiv2M(EarlyTermShiftDiv2), .ZSgnEffM(ZSgnEffE), .PSgnM(PSgnE), .FmtM(ModFmt), .FrmM(FrmVal),
|
||||
.KillProdM(KillProdE), .AddendStickyM(AddendStickyE), .ProdExpM(Pe),
|
||||
.SumM(Sm), .NegSumM(NegSumE), .InvZM(InvZE), .FmaNormCntM(FmaNormCntE), .EarlyTermShiftDiv2M(EarlyTermShiftDiv2), .ZSgnEffM(ZSgnEffE), .PSgnM(Ps), .FmtM(ModFmt), .FrmM(FrmVal),
|
||||
.PostProcFlgM(Flg), .PostProcResM(FpRes), .FCvtIntResM(IntRes));
|
||||
|
||||
fcvt fcvt (.XSgnE(XSgn), .XExpE(XExp), .XManE(XMan), .ForwardedSrcAE(SrcA), .FWriteIntE(WriteIntVal),
|
||||
|
Loading…
Reference in New Issue
Block a user