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