mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main
This commit is contained in:
commit
32a4afc7a1
@ -28,6 +28,7 @@
|
|||||||
// `define NE 11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8)
|
// `define NE 11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8)
|
||||||
// `define NF 52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23)
|
// `define NF 52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23)
|
||||||
// `define XLEN 64
|
// `define XLEN 64
|
||||||
|
`define NANPAYLOAD 1
|
||||||
module fma(
|
module fma(
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic reset,
|
input logic reset,
|
||||||
@ -117,9 +118,8 @@ module fma1(
|
|||||||
logic [3*`NF+6:0] AlignedAddendInv; // aligned addend possibly inverted
|
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] ProdManKilled; // the product's mantissa possibly killed
|
||||||
logic [3*`NF+4:0] NegProdManKilled; // a negated ProdManKilled
|
logic [3*`NF+4:0] NegProdManKilled; // a negated ProdManKilled
|
||||||
logic [8:0] PNormCnt, NNormCnt; // the positive and nagitive LOA results
|
|
||||||
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
|
||||||
|
logic [`NE-1:0] XExpVal, YExpVal; // exponent value after taking into accound denormals
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Calculate the product
|
// Calculate the product
|
||||||
// - When multipliying two fp numbers, add the exponents
|
// - When multipliying two fp numbers, add the exponents
|
||||||
@ -130,7 +130,7 @@ module fma1(
|
|||||||
|
|
||||||
|
|
||||||
// calculate the product's exponent
|
// calculate the product's exponent
|
||||||
expadd expadd(.FmtE, .XExpE, .YExpE, .XZeroE, .YZeroE, .XDenormE, .YDenormE,
|
expadd expadd(.FmtE, .XExpE, .YExpE, .XZeroE, .YZeroE, .XDenormE, .YDenormE, .XExpVal, .YExpVal,
|
||||||
.Denorm, .ProdExpE);
|
.Denorm, .ProdExpE);
|
||||||
|
|
||||||
// multiplication of the mantissa's
|
// multiplication of the mantissa's
|
||||||
@ -140,7 +140,7 @@ module fma1(
|
|||||||
// Alignment shifter
|
// Alignment shifter
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
align align(.ZExpE, .ZManE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, .ProdExpE, .Denorm,
|
align align(.ZExpE, .ZManE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, .ProdExpE, .Denorm, .XExpVal, .YExpVal,
|
||||||
.AlignedAddendE, .AddendStickyE, .KillProdE);
|
.AlignedAddendE, .AddendStickyE, .KillProdE);
|
||||||
|
|
||||||
// calculate the signs and take the opperation into account
|
// calculate the signs and take the opperation into account
|
||||||
@ -150,9 +150,9 @@ module fma1(
|
|||||||
// // Addition/LZA
|
// // Addition/LZA
|
||||||
// ///////////////////////////////////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
add add(.AlignedAddendE, .ProdManE, .PSgnE, .ZSgnEffE, .KillProdE, .AlignedAddendInv, .ProdManKilled, .NegProdManKilled, .NegSumE, .PreSum, .NegPreSum, .InvZE, .XZeroE, .YZeroE);
|
add add(.AlignedAddendE, .ProdManE, .PSgnE, .ZSgnEffE, .KillProdE, .AlignedAddendInv, .ProdManKilled, .NegSumE, .PreSum, .NegPreSum, .InvZE, .XZeroE, .YZeroE);
|
||||||
|
|
||||||
loa loa(.A(AlignedAddendInv+{162'b0,InvZE}), .P(ProdManKilled), .NegSumE, .NormCntE);
|
loa loa(.A(AlignedAddendInv+{162'b0,InvZE}), .P(ProdManKilled), .NormCntE);
|
||||||
|
|
||||||
// Choose the positive sum and accompanying LZA result.
|
// Choose the positive sum and accompanying LZA result.
|
||||||
assign SumE = NegSumE ? NegPreSum[3*`NF+5:0] : PreSum[3*`NF+5:0];
|
assign SumE = NegSumE ? NegPreSum[3*`NF+5:0] : PreSum[3*`NF+5:0];
|
||||||
@ -167,11 +167,11 @@ module expadd(
|
|||||||
input logic [`NE-1:0] XExpE, YExpE, // input exponents
|
input logic [`NE-1:0] XExpE, YExpE, // input exponents
|
||||||
input logic XDenormE, YDenormE, // are the inputs denormalized
|
input logic XDenormE, YDenormE, // are the inputs denormalized
|
||||||
input logic XZeroE, YZeroE, // are the inputs zero
|
input logic XZeroE, YZeroE, // are the inputs zero
|
||||||
|
output logic [`NE-1:0] XExpVal, YExpVal, // Exponent value after taking into account denormals
|
||||||
output logic [`NE-1:0] Denorm, // value of denormalized exponent
|
output logic [`NE-1:0] Denorm, // value of denormalized exponent
|
||||||
output logic [`NE+1:0] ProdExpE // product's exponent B^(1023)NE+2
|
output logic [`NE+1:0] ProdExpE // product's exponent B^(1023)NE+2
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [`NE-1:0] XExpVal, YExpVal; // Exponent value after taking into account denormals
|
|
||||||
|
|
||||||
// denormalized numbers have diffrent values depending on which precison it is.
|
// denormalized numbers have diffrent values depending on which precison it is.
|
||||||
// double - 1
|
// double - 1
|
||||||
@ -233,6 +233,7 @@ module align(
|
|||||||
input logic [`NF:0] ZManE, // fractions in U(0.NF) format]
|
input logic [`NF:0] ZManE, // fractions in U(0.NF) format]
|
||||||
input logic ZDenormE, // is the input denormal
|
input logic ZDenormE, // is the input denormal
|
||||||
input logic XZeroE, YZeroE, ZZeroE, // is the input zero
|
input logic XZeroE, YZeroE, ZZeroE, // is the input zero
|
||||||
|
input logic [`NE-1:0] XExpVal, YExpVal, // Exponent value after taking into account denormals
|
||||||
input logic [`NE+1:0] ProdExpE, // the product's exponent
|
input logic [`NE+1:0] ProdExpE, // the product's exponent
|
||||||
input logic [`NE-1:0] Denorm, // the biased value of a denormalized number
|
input logic [`NE-1:0] Denorm, // the biased value of a denormalized number
|
||||||
output logic [3*`NF+5:0] AlignedAddendE, // Z aligned for addition in U(NF+5.2NF+1)
|
output logic [3*`NF+5:0] AlignedAddendE, // Z aligned for addition in U(NF+5.2NF+1)
|
||||||
@ -254,7 +255,8 @@ module align(
|
|||||||
// - positive means the product is larger, so shift Z right
|
// - positive means the product is larger, so shift Z right
|
||||||
// - Denormal numbers have a diffrent exponent value depending on the precision
|
// - Denormal numbers have a diffrent exponent value depending on the precision
|
||||||
assign ZExpVal = ZDenormE ? Denorm : ZExpE;
|
assign ZExpVal = ZDenormE ? Denorm : ZExpE;
|
||||||
assign AlignCnt = ProdExpE - {2'b0, ZExpVal} + (`NF+3);
|
// assign AlignCnt = ProdExpE - {2'b0, ZExpVal} + (`NF+3);
|
||||||
|
assign AlignCnt = XZeroE|YZeroE ? -1 : {2'b0, XExpVal} + {2'b0, YExpVal} - 1020+`NF - {2'b0, ZExpVal};
|
||||||
|
|
||||||
// Defualt Addition without shifting
|
// Defualt Addition without shifting
|
||||||
// | 54'b0 | 106'b(product) | 2'b0 |
|
// | 54'b0 | 106'b(product) | 2'b0 |
|
||||||
@ -312,14 +314,14 @@ module add(
|
|||||||
input logic PSgnE, ZSgnEffE,// the product and modified Z signs
|
input logic PSgnE, 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] AlignedAddendInv, // aligned addend possibly inverted
|
||||||
output logic [2*`NF+1:0] ProdManKilled, // the product's mantissa possibly killed
|
output logic [2*`NF+1:0] ProdManKilled, // the product's mantissa possibly killed
|
||||||
output logic [3*`NF+4:0] NegProdManKilled, // a negated ProdManKilled
|
|
||||||
output logic NegSumE, // was the sum negitive
|
output logic NegSumE, // was the sum negitive
|
||||||
output logic InvZE, // do you invert Z
|
output logic InvZE, // do you invert Z
|
||||||
output logic [3*`NF+6:0] PreSum, NegPreSum// possibly negitive sum
|
output logic [3*`NF+6:0] PreSum, NegPreSum// possibly negitive sum
|
||||||
);
|
);
|
||||||
|
|
||||||
|
logic [3*`NF+4:0] NegProdManKilled; // a negated ProdManKilled
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Addition
|
// Addition
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -334,17 +336,17 @@ module add(
|
|||||||
// 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 ProdManKilled = ProdManE&{2*`NF+2{~KillProdE}};
|
||||||
// Negate ProdMan for LZA and the negitive sum calculation
|
// Negate ProdMan for LZA and the negitive sum calculation
|
||||||
assign NegProdManKilled = {{`NF+3{~(XZeroE|YZeroE|KillProdE)}}, ~ProdManKilled&{2*`NF+2{~(XZeroE|YZeroE)}}};
|
assign NegProdManKilled = {{`NF+3{~(XZeroE|YZeroE|KillProdE)}}, ~ProdManKilled&{2*`NF+2{~(XZeroE|YZeroE|KillProdE)}}};
|
||||||
|
|
||||||
|
|
||||||
// Is the sum negitive
|
|
||||||
assign NegSumE = (AlignedAddendE > {54'b0, ProdManKilled, 2'b0})&InvZE; //***use this to avoid addition and final muxing???
|
|
||||||
|
|
||||||
// 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 + {55'b0, ProdManKilled, 2'b0} + {{3*`NF+6{1'b0}}, InvZE};
|
assign PreSum = AlignedAddendInv + {55'b0, ProdManKilled, 2'b0} + {{3*`NF+6{1'b0}}, InvZE};
|
||||||
assign NegPreSum = AlignedAddendE + {NegProdManKilled, 2'b0} + {{(3*`NF+3){1'b0}},~(XZeroE|YZeroE),2'b0};
|
assign NegPreSum = AlignedAddendE + {NegProdManKilled, 2'b0} + {{(3*`NF+3){1'b0}},~(XZeroE|YZeroE|KillProdE),2'b0};
|
||||||
|
|
||||||
|
// Is the sum negitive
|
||||||
|
assign NegSumE = PreSum[3*`NF+6];
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
@ -352,28 +354,32 @@ endmodule
|
|||||||
module loa( //https://ieeexplore.ieee.org/abstract/document/930098
|
module loa( //https://ieeexplore.ieee.org/abstract/document/930098
|
||||||
input logic [3*`NF+6:0] A, // addend
|
input logic [3*`NF+6:0] A, // addend
|
||||||
input logic [2*`NF+1:0] P, // product
|
input logic [2*`NF+1:0] P, // product
|
||||||
input logic NegSumE, // is the sum negitive
|
|
||||||
output logic [8:0] NormCntE // normalization shift count for the positive result
|
output logic [8:0] NormCntE // normalization shift count for the positive result
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
logic [3*`NF+6:0] T;
|
logic [3*`NF+6:0] T;
|
||||||
logic [3*`NF+5:0] G;
|
logic [3*`NF+6:0] G;
|
||||||
logic [3*`NF+5:0] Z;
|
logic [3*`NF+6:0] Z;
|
||||||
assign T[3*`NF+6:2*`NF+4] = A[3*`NF+6:2*`NF+4];
|
assign T[3*`NF+6:2*`NF+4] = A[3*`NF+6:2*`NF+4];
|
||||||
assign G[3*`NF+5:2*`NF+4] = 0;
|
assign G[3*`NF+6:2*`NF+4] = 0;
|
||||||
assign Z[3*`NF+5:2*`NF+4] = ~A[3*`NF+5:2*`NF+4];
|
assign Z[3*`NF+6:2*`NF+4] = ~A[3*`NF+6:2*`NF+4];
|
||||||
assign T[2*`NF+3:2] = A[2*`NF+3:2]^P;
|
assign T[2*`NF+3:2] = A[2*`NF+3:2]^P;
|
||||||
assign G[2*`NF+3:2] = A[2*`NF+3:2]&P;
|
assign G[2*`NF+3:2] = A[2*`NF+3:2]&P;
|
||||||
assign Z[2*`NF+3:2] = ~A[2*`NF+3:2]&~P;
|
assign Z[2*`NF+3:2] = ~A[2*`NF+3:2]&~P;
|
||||||
assign T[1:0] = A[1:0];
|
assign T[1:0] = A[1:0];
|
||||||
assign G[1:0] = 0;
|
assign G[1:0] = 0;
|
||||||
assign Z[1:0] = ~A[1:0];
|
assign Z[1:0] = ~A[1:0];
|
||||||
|
|
||||||
|
|
||||||
// Apply function to determine Leading pattern
|
// Apply function to determine Leading pattern
|
||||||
|
// - note: the paper linked above uses the numbering system where 0 is the most significant bit
|
||||||
|
//f[n] = ~T[n]&T[n-1] note: n is the MSB
|
||||||
|
//f[i] = (T[i+1]&(G[i]&~Z[i-1] | Z[i]&~G[i-1])) | (~T[i+1]&(Z[i]&~Z[i-1] | G[i]&~G[i-1]))
|
||||||
logic [3*`NF+6:0] f;
|
logic [3*`NF+6:0] f;
|
||||||
assign f = NegSumE ? T^{~G[3*`NF+5:0],1'b1} : T^{~Z[3*`NF+5:0], 1'b1};
|
assign f[3*`NF+6] = ~T[3*`NF+6]&T[3*`NF+5];
|
||||||
|
assign f[3*`NF+5:0] = (T[3*`NF+6:1]&(G[3*`NF+5:0]&{~Z[3*`NF+4:0], 1'b0} | Z[3*`NF+5:0]&{~G[3*`NF+4:0], 1'b1})) | (~T[3*`NF+6:1]&(Z[3*`NF+5:0]&{~Z[3*`NF+4:0], 1'b0} | G[3*`NF+5:0]&{~G[3*`NF+4:0], 1'b1}));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
lzc lzc(.f, .NormCntE);
|
lzc lzc(.f, .NormCntE);
|
||||||
|
|
||||||
@ -426,7 +432,7 @@ module fma2(
|
|||||||
|
|
||||||
logic [`NF-1:0] ResultFrac; // Result fraction
|
logic [`NF-1:0] ResultFrac; // Result fraction
|
||||||
logic [`NE-1:0] ResultExp; // Result exponent
|
logic [`NE-1:0] ResultExp; // Result exponent
|
||||||
logic ResultSgn; // Result sign
|
logic ResultSgn, ResultSgnTmp; // Result sign
|
||||||
logic [`NE+1:0] SumExp; // exponent of the normalized sum
|
logic [`NE+1:0] SumExp; // exponent of the normalized sum
|
||||||
logic [`NE+1:0] FullResultExp; // ResultExp with bits to determine sign and overflow
|
logic [`NE+1:0] FullResultExp; // ResultExp with bits to determine sign and overflow
|
||||||
logic [`NF+2:0] NormSum; // normalized sum
|
logic [`NF+2:0] NormSum; // normalized sum
|
||||||
@ -464,7 +470,7 @@ module fma2(
|
|||||||
// round to infinity
|
// round to infinity
|
||||||
// round to nearest max magnitude
|
// round to nearest max magnitude
|
||||||
|
|
||||||
fmaround fmaround(.FmtM, .FrmM, .Sticky, .UfSticky, .NormSum, .AddendStickyM, .NormSumSticky, .ZZeroM, .InvZM, .ResultSgn, .SumExp,
|
fmaround fmaround(.FmtM, .FrmM, .Sticky, .UfSticky, .NormSum, .AddendStickyM, .NormSumSticky, .ZZeroM, .InvZM, .ResultSgnTmp, .SumExp,
|
||||||
.CalcPlus1, .Plus1, .UfPlus1, .Minus1, .FullResultExp, .ResultFrac, .ResultExp, .Round, .Guard, .UfLSBNormSum);
|
.CalcPlus1, .Plus1, .UfPlus1, .Minus1, .FullResultExp, .ResultFrac, .ResultExp, .Round, .Guard, .UfLSBNormSum);
|
||||||
|
|
||||||
|
|
||||||
@ -476,7 +482,7 @@ module fma2(
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
resultsign resultsign(.FrmM, .PSgnM, .ZSgnEffM, .Underflow, .InvZM, .NegSumM, .SumZero, .ResultSgn);
|
resultsign resultsign(.FrmM, .PSgnM, .ZSgnEffM, .Underflow, .InvZM, .NegSumM, .SumZero, .ResultSgnTmp, .ResultSgn);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -512,11 +518,12 @@ module resultsign(
|
|||||||
input logic InvZM,
|
input logic InvZM,
|
||||||
input logic NegSumM,
|
input logic NegSumM,
|
||||||
input logic SumZero,
|
input logic SumZero,
|
||||||
|
output logic ResultSgnTmp,
|
||||||
output logic ResultSgn
|
output logic ResultSgn
|
||||||
);
|
);
|
||||||
|
|
||||||
logic ZeroSgn;
|
logic ZeroSgn;
|
||||||
logic ResultSgnTmp;
|
// logic ResultSgnTmp;
|
||||||
|
|
||||||
// Determine the sign if the sum is zero
|
// Determine the sign if the sum is zero
|
||||||
// if cancelation then 0 unless round to -infinity
|
// if cancelation then 0 unless round to -infinity
|
||||||
@ -554,15 +561,24 @@ module resultselect(
|
|||||||
);
|
);
|
||||||
logic [`FLEN-1:0] XNaNResult, YNaNResult, ZNaNResult, InvalidResult, OverflowResult, KillProdResult, UnderflowResult; // possible results
|
logic [`FLEN-1:0] XNaNResult, YNaNResult, ZNaNResult, InvalidResult, OverflowResult, KillProdResult, UnderflowResult; // possible results
|
||||||
|
|
||||||
assign XNaNResult = FmtM ? {XSgnM, XExpM, 1'b1, XManM[`NF-2:0]} : {{32{1'b1}}, XSgnM, XExpM[7:0], 1'b1, XManM[50:29]};
|
generate if(`NANPAYLOAD) begin
|
||||||
assign YNaNResult = FmtM ? {YSgnM, YExpM, 1'b1, YManM[`NF-2:0]} : {{32{1'b1}}, YSgnM, YExpM[7:0], 1'b1, YManM[50:29]};
|
assign XNaNResult = FmtM ? {XSgnM, XExpM, 1'b1, XManM[`NF-2:0]} : {{32{1'b1}}, XSgnM, XExpM[7:0], 1'b1, XManM[50:29]};
|
||||||
assign ZNaNResult = FmtM ? {ZSgnEffM, ZExpM, 1'b1, ZManM[`NF-2:0]} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], 1'b1, ZManM[50:29]};
|
assign YNaNResult = FmtM ? {YSgnM, YExpM, 1'b1, YManM[`NF-2:0]} : {{32{1'b1}}, YSgnM, YExpM[7:0], 1'b1, YManM[50:29]};
|
||||||
|
assign ZNaNResult = FmtM ? {ZSgnEffM, ZExpM, 1'b1, ZManM[`NF-2:0]} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], 1'b1, ZManM[50:29]};
|
||||||
|
end else begin
|
||||||
|
assign XNaNResult = FmtM ? {XSgnM, XExpM, 1'b1, 51'b0} : {{32{1'b1}}, XSgnM, XExpM[7:0], 1'b1, 22'b0};
|
||||||
|
assign YNaNResult = FmtM ? {YSgnM, YExpM, 1'b1, 51'b0} : {{32{1'b1}}, YSgnM, YExpM[7:0], 1'b1, 22'b0};
|
||||||
|
assign ZNaNResult = FmtM ? {ZSgnEffM, ZExpM, 1'b1, 51'b0} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], 1'b1, 22'b0};
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
|
||||||
assign OverflowResult = FmtM ? ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} :
|
assign OverflowResult = FmtM ? ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} :
|
||||||
{ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}} :
|
{ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}} :
|
||||||
((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{32{1'b1}}, ResultSgn, 8'hfe, {23{1'b1}}} :
|
((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{32{1'b1}}, ResultSgn, 8'hfe, {23{1'b1}}} :
|
||||||
{{32{1'b1}}, ResultSgn, 8'hff, 23'b0};
|
{{32{1'b1}}, ResultSgn, 8'hff, 23'b0};
|
||||||
assign InvalidResult = FmtM ? {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{32{1'b1}}, ResultSgn, 8'hff, 1'b1, 22'b0};
|
assign InvalidResult = FmtM ? {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{32{1'b1}}, ResultSgn, 8'hff, 1'b1, 22'b0};
|
||||||
assign KillProdResult = FmtM ? {ResultSgn, {ZExpM, ZManM[`NF-1:0]} - {62'b0, (Minus1&AddendStickyM) + (Plus1&AddendStickyM)}} : {{32{1'b1}}, ResultSgn, {ZExpM[`NE-1],ZExpM[6:0], ZManM[51:29]} - {30'b0, (Minus1&AddendStickyM)} + {30'b0, (Plus1&AddendStickyM)}};
|
assign KillProdResult = FmtM ? {ResultSgn, {ZExpM, ZManM[`NF-1:0]} - {62'b0, (Minus1&AddendStickyM)} + {62'b0, (Plus1&AddendStickyM)}} : {{32{1'b1}}, ResultSgn, {ZExpM[`NE-1],ZExpM[6:0], ZManM[51:29]} - {30'b0, (Minus1&AddendStickyM)} + {30'b0, (Plus1&AddendStickyM)}};
|
||||||
assign UnderflowResult = FmtM ? {ResultSgn, {`FLEN-1{1'b0}}} + {63'b0,(CalcPlus1&(AddendStickyM|FrmM[1]))} : {{32{1'b1}}, {ResultSgn, 31'b0} + {31'b0, (CalcPlus1&(AddendStickyM|FrmM[1]))}};
|
assign UnderflowResult = FmtM ? {ResultSgn, {`FLEN-1{1'b0}}} + {63'b0,(CalcPlus1&(AddendStickyM|FrmM[1]))} : {{32{1'b1}}, {ResultSgn, 31'b0} + {31'b0, (CalcPlus1&(AddendStickyM|FrmM[1]))}};
|
||||||
assign FMAResM = XNaNM ? XNaNResult :
|
assign FMAResM = XNaNM ? XNaNResult :
|
||||||
YNaNM ? YNaNResult :
|
YNaNM ? YNaNResult :
|
||||||
@ -579,81 +595,6 @@ module resultselect(
|
|||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
// module normalize(
|
|
||||||
// input logic [3*`NF+5:0] SumM, // the positive sum
|
|
||||||
// input logic [`NE-1:0] ZExpM, // exponent of Z
|
|
||||||
// input logic [`NE+1:0] ProdExpM, // X exponent + Y exponent - bias
|
|
||||||
// input logic [8:0] NormCntM, // normalization shift count
|
|
||||||
// input logic FmtM, // precision 1 = double 0 = single
|
|
||||||
// input logic KillProdM, // is the product set to zero
|
|
||||||
// input logic AddendStickyM, // the sticky bit caclulated from the aligned addend
|
|
||||||
// input logic NegSumM, // was the sum negitive
|
|
||||||
// output logic [`NF+2:0] NormSum, // normalized sum
|
|
||||||
// output logic SumZero, // is the sum zero
|
|
||||||
// output logic NormSumSticky, UfSticky, // sticky bits
|
|
||||||
// output logic [`NE+1:0] SumExp, // exponent of the normalized sum
|
|
||||||
// output logic ResultDenorm // is the result denormalized
|
|
||||||
// );
|
|
||||||
// logic [`NE+1:0] FracLen; // length of the fraction
|
|
||||||
// logic [`NE+1:0] SumExpTmp; // exponent of the normalized sum not taking into account denormal or zero results
|
|
||||||
// logic [8:0] DenormShift; // right shift if the result is denormalized //***change this later
|
|
||||||
// logic [3*`NF+5:0] CorrSumShifted; // the shifted sum after LZA correction
|
|
||||||
// logic [3*`NF+7:0] SumShifted; // the shifted sum before LZA correction
|
|
||||||
// logic [`NE+1:0] SumExpTmpTmp; // the exponent of the normalized sum with the `FLEN bias
|
|
||||||
// logic PreResultDenorm; // is the result denormalized - calculated before LZA corection
|
|
||||||
// logic PreResultDenorm2; // is the result denormalized - calculated before LZA corection
|
|
||||||
// logic LZAPlus1; // add one to the sum's exponent due to LZA correction
|
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// // Normalization
|
|
||||||
// ///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// // Determine if the sum is zero
|
|
||||||
// assign SumZero = ~(|SumM);
|
|
||||||
|
|
||||||
// // determine the length of the fraction based on precision
|
|
||||||
// assign FracLen = FmtM ? `NF+1 : 13'd24;
|
|
||||||
|
|
||||||
// // calculate the sum's exponent
|
|
||||||
// assign SumExpTmpTmp = KillProdM ? {2'b0, ZExpM} : ProdExpM + -({4'b0, NormCntM} + 1 - (`NF+4)); // ****try moving this into previous stage
|
|
||||||
// assign SumExpTmp = FmtM ? SumExpTmpTmp : (SumExpTmpTmp-1023+127)&{`NE+2{|SumExpTmpTmp}}; // ***move this ^ the subtraction by a constant isn't simplified
|
|
||||||
|
|
||||||
// logic SumDLTEZ, SumDGEFL, SumSLTEZ, SumSGEFL;
|
|
||||||
// assign SumDLTEZ = SumExpTmpTmp[`NE+1] | ~|SumExpTmpTmp;
|
|
||||||
// assign SumDGEFL = ($signed(SumExpTmpTmp)>=$signed(-(13'd`NF+13'd1)));
|
|
||||||
// assign SumSLTEZ = $signed(SumExpTmpTmp) <= $signed(13'd1023-13'd127);
|
|
||||||
// assign SumSGEFL = ($signed(SumExpTmpTmp)>=$signed(-13'd24+13'd1023-13'd127)) | ~|SumExpTmpTmp;
|
|
||||||
// assign PreResultDenorm2 = (FmtM ? SumDLTEZ : SumSLTEZ) & (FmtM ? SumDGEFL : SumSGEFL) & ~SumZero; //***make sure math good
|
|
||||||
// // always_comb begin
|
|
||||||
// // assert (PreResultDenorm == PreResultDenorm2) else $fatal ("PreResultDenorms not equal");
|
|
||||||
// // end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// // Determine if the result is denormal
|
|
||||||
// // assign PreResultDenorm = $signed(SumExpTmp)<=0 & ($signed(SumExpTmp)>=$signed(-FracLen)) & ~SumZero;
|
|
||||||
|
|
||||||
// // Determine the shift needed for denormal results
|
|
||||||
// // - if not denorm add 1 to shift out the leading 1
|
|
||||||
// assign DenormShift = PreResultDenorm2 ? SumExpTmp[8:0] : 1; //*** change this when changing the size of DenormShift also change to an and opperation
|
|
||||||
// // Normalize the sum
|
|
||||||
// assign SumShifted = {2'b0, SumM} << NormCntM+DenormShift; //*** fix mux's with constants in them //***NormCnt can be simplified
|
|
||||||
// // LZA correction
|
|
||||||
// assign LZAPlus1 = SumShifted[3*`NF+7];
|
|
||||||
// assign CorrSumShifted = LZAPlus1 ? SumShifted[3*`NF+6:1] : SumShifted[3*`NF+5:0];
|
|
||||||
// assign NormSum = CorrSumShifted[3*`NF+5:2*`NF+3];
|
|
||||||
// // Calculate the sticky bit
|
|
||||||
// assign NormSumSticky = (|CorrSumShifted[2*`NF+2:0]) | (|CorrSumShifted[136:2*`NF+3]&~FmtM);
|
|
||||||
// assign UfSticky = AddendStickyM | NormSumSticky;
|
|
||||||
|
|
||||||
// // Determine sum's exponent
|
|
||||||
// assign SumExp = (SumExpTmp+{12'b0, LZAPlus1}+{12'b0, ~|SumExpTmp&SumShifted[3*`NF+6]}) & {`NE+2{~(SumZero|ResultDenorm)}};
|
|
||||||
// // recalculate if the result is denormalized
|
|
||||||
// assign ResultDenorm = PreResultDenorm2&~SumShifted[3*`NF+6]&~SumShifted[3*`NF+7];
|
|
||||||
|
|
||||||
// endmodule
|
|
||||||
|
|
||||||
module normalize(
|
module normalize(
|
||||||
input logic [3*`NF+5:0] SumM, // the positive sum
|
input logic [3*`NF+5:0] SumM, // the positive sum
|
||||||
input logic [`NE-1:0] ZExpM, // exponent of Z
|
input logic [`NE-1:0] ZExpM, // exponent of Z
|
||||||
@ -733,7 +674,7 @@ module normalize(
|
|||||||
assign LZAPlus1 = SumShifted[3*`NF+7];
|
assign LZAPlus1 = SumShifted[3*`NF+7];
|
||||||
assign LZAPlus2 = SumShifted[3*`NF+8];
|
assign LZAPlus2 = SumShifted[3*`NF+8];
|
||||||
// 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
|
// 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
|
||||||
assign CorrSumShifted = LZAPlus1 ? SumShifted[3*`NF+6:1] : SumShifted[3*`NF+5:0];
|
assign CorrSumShifted = LZAPlus1&~KillProdM ? SumShifted[3*`NF+6:1] : SumShifted[3*`NF+5:0];
|
||||||
assign NormSum = CorrSumShifted[3*`NF+5:2*`NF+3];
|
assign NormSum = CorrSumShifted[3*`NF+5:2*`NF+3];
|
||||||
// Calculate the sticky bit
|
// Calculate the sticky bit
|
||||||
assign NormSumSticky = (|CorrSumShifted[2*`NF+2:0]) | (|CorrSumShifted[136:2*`NF+3]&~FmtM);
|
assign NormSumSticky = (|CorrSumShifted[2*`NF+2:0]) | (|CorrSumShifted[136:2*`NF+3]&~FmtM);
|
||||||
@ -757,7 +698,7 @@ module fmaround(
|
|||||||
input logic ZZeroM, // is Z zero
|
input logic ZZeroM, // is Z zero
|
||||||
input logic InvZM, // invert Z
|
input logic InvZM, // invert Z
|
||||||
input logic [`NE+1:0] SumExp, // exponent of the normalized sum
|
input logic [`NE+1:0] SumExp, // exponent of the normalized sum
|
||||||
input logic ResultSgn, // the result's sign
|
input logic ResultSgnTmp, // the result's sign
|
||||||
output logic CalcPlus1, Plus1, UfPlus1, Minus1, // do you add or subtract on from the result
|
output logic CalcPlus1, Plus1, UfPlus1, Minus1, // do you add or subtract on from the result
|
||||||
output logic [`NE+1:0] FullResultExp, // ResultExp with bits to determine sign and overflow
|
output logic [`NE+1:0] FullResultExp, // ResultExp with bits to determine sign and overflow
|
||||||
output logic [`NF-1:0] ResultFrac, // Result fraction
|
output logic [`NF-1:0] ResultFrac, // Result fraction
|
||||||
@ -824,8 +765,8 @@ module fmaround(
|
|||||||
case (FrmM)
|
case (FrmM)
|
||||||
3'b000: CalcPlus1 = Guard & (Round | ((Sticky)&~(~Round&SubBySmallNum)) | (~Round&~(Sticky)&LSBNormSum&~SubBySmallNum));//round to nearest even
|
3'b000: CalcPlus1 = Guard & (Round | ((Sticky)&~(~Round&SubBySmallNum)) | (~Round&~(Sticky)&LSBNormSum&~SubBySmallNum));//round to nearest even
|
||||||
3'b001: CalcPlus1 = 0;//round to zero
|
3'b001: CalcPlus1 = 0;//round to zero
|
||||||
3'b010: CalcPlus1 = ResultSgn & ~(SubBySmallNum & ~Guard & ~Round);//round down
|
3'b010: CalcPlus1 = ResultSgnTmp & ~(SubBySmallNum & ~Guard & ~Round);//round down
|
||||||
3'b011: CalcPlus1 = ~ResultSgn & ~(SubBySmallNum & ~Guard & ~Round);//round up
|
3'b011: CalcPlus1 = ~ResultSgnTmp & ~(SubBySmallNum & ~Guard & ~Round);//round up
|
||||||
3'b100: CalcPlus1 = (Guard & (Round | ((Sticky)&~(~Round&SubBySmallNum)) | (~Round&~(Sticky)&~SubBySmallNum)));//round to nearest max magnitude
|
3'b100: CalcPlus1 = (Guard & (Round | ((Sticky)&~(~Round&SubBySmallNum)) | (~Round&~(Sticky)&~SubBySmallNum)));//round to nearest max magnitude
|
||||||
default: CalcPlus1 = 1'bx;
|
default: CalcPlus1 = 1'bx;
|
||||||
endcase
|
endcase
|
||||||
@ -833,8 +774,8 @@ module fmaround(
|
|||||||
case (FrmM)
|
case (FrmM)
|
||||||
3'b000: UfCalcPlus1 = UfGuard & (UfRound | (UfSticky&UfRound|~UfSubBySmallNum) | (~Sticky&UfLSBNormSum&~UfSubBySmallNum));//round to nearest even
|
3'b000: UfCalcPlus1 = UfGuard & (UfRound | (UfSticky&UfRound|~UfSubBySmallNum) | (~Sticky&UfLSBNormSum&~UfSubBySmallNum));//round to nearest even
|
||||||
3'b001: UfCalcPlus1 = 0;//round to zero
|
3'b001: UfCalcPlus1 = 0;//round to zero
|
||||||
3'b010: UfCalcPlus1 = ResultSgn & ~(UfSubBySmallNum & ~UfGuard & ~UfRound);//round down
|
3'b010: UfCalcPlus1 = ResultSgnTmp & ~(UfSubBySmallNum & ~UfGuard & ~UfRound);//round down
|
||||||
3'b011: UfCalcPlus1 = ~ResultSgn & ~(UfSubBySmallNum & ~UfGuard & ~UfRound);//round up
|
3'b011: UfCalcPlus1 = ~ResultSgnTmp & ~(UfSubBySmallNum & ~UfGuard & ~UfRound);//round up
|
||||||
3'b100: UfCalcPlus1 = (UfGuard & (UfRound | (UfSticky&~(~UfRound&UfSubBySmallNum)) | (~Sticky&~UfSubBySmallNum)));//round to nearest max magnitude
|
3'b100: UfCalcPlus1 = (UfGuard & (UfRound | (UfSticky&~(~UfRound&UfSubBySmallNum)) | (~Sticky&~UfSubBySmallNum)));//round to nearest max magnitude
|
||||||
default: UfCalcPlus1 = 1'bx;
|
default: UfCalcPlus1 = 1'bx;
|
||||||
endcase
|
endcase
|
||||||
@ -842,8 +783,8 @@ module fmaround(
|
|||||||
case (FrmM)
|
case (FrmM)
|
||||||
3'b000: CalcMinus1 = 0;//round to nearest even
|
3'b000: CalcMinus1 = 0;//round to nearest even
|
||||||
3'b001: CalcMinus1 = SubBySmallNum & ~Guard & ~Round;//round to zero
|
3'b001: CalcMinus1 = SubBySmallNum & ~Guard & ~Round;//round to zero
|
||||||
3'b010: CalcMinus1 = ~ResultSgn & ~Guard & ~Round & SubBySmallNum;//round down
|
3'b010: CalcMinus1 = ~ResultSgnTmp & ~Guard & ~Round & SubBySmallNum;//round down
|
||||||
3'b011: CalcMinus1 = ResultSgn & ~Guard & ~Round & SubBySmallNum;//round up
|
3'b011: CalcMinus1 = ResultSgnTmp & ~Guard & ~Round & SubBySmallNum;//round up
|
||||||
3'b100: CalcMinus1 = 0;//round to nearest max magnitude
|
3'b100: CalcMinus1 = 0;//round to nearest max magnitude
|
||||||
default: CalcMinus1 = 1'bx;
|
default: CalcMinus1 = 1'bx;
|
||||||
endcase
|
endcase
|
||||||
|
@ -33,7 +33,6 @@ module alu #(parameter WIDTH=32) (
|
|||||||
output logic [WIDTH-1:0] Sum);
|
output logic [WIDTH-1:0] Sum);
|
||||||
|
|
||||||
logic [WIDTH-1:0] CondInvB, Shift, SLT, SLTU, FullResult;
|
logic [WIDTH-1:0] CondInvB, Shift, SLT, SLTU, FullResult;
|
||||||
logic Right;
|
|
||||||
logic Carry, Neg;
|
logic Carry, Neg;
|
||||||
logic LT, LTU;
|
logic LT, LTU;
|
||||||
logic Overflow;
|
logic Overflow;
|
||||||
@ -51,13 +50,12 @@ module alu #(parameter WIDTH=32) (
|
|||||||
assign {Carry, Sum} = A + CondInvB + {{(WIDTH-1){1'b0}}, SubArith};
|
assign {Carry, Sum} = A + CondInvB + {{(WIDTH-1){1'b0}}, SubArith};
|
||||||
|
|
||||||
// Shifts
|
// Shifts
|
||||||
assign Right = (Funct3[2:0] == 3'b101); // sra or srl
|
shifter sh(.A, .Amt(B[`LOG_XLEN-1:0]), .Right(Funct3[2]), .Arith(SubArith), .W64, .Y(Shift));
|
||||||
shifter sh(A, B[5:0], Right, SubArith, W64, Shift);
|
|
||||||
|
// condition code flags based on subtract output
|
||||||
// condition code flags based on add/subtract output
|
// Overflow occurs when the numbers being subtracted have the opposite sign
|
||||||
// Overflow occurs when the numbers being added have the same sign
|
// and the result has the opposite sign of A
|
||||||
// and the result has the opposite sign
|
assign Overflow = (A[WIDTH-1] ^ B[WIDTH-1]) & (A[WIDTH-1] ^ Sum[WIDTH-1]);
|
||||||
assign Overflow = (A[WIDTH-1] ~^ CondInvB[WIDTH-1]) & (A[WIDTH-1] ^ Sum[WIDTH-1]);
|
|
||||||
assign Neg = Sum[WIDTH-1];
|
assign Neg = Sum[WIDTH-1];
|
||||||
assign LT = Neg ^ Overflow;
|
assign LT = Neg ^ Overflow;
|
||||||
assign LTU = ~Carry;
|
assign LTU = ~Carry;
|
||||||
|
@ -30,7 +30,7 @@ module comparator #(parameter WIDTH=32) (
|
|||||||
output logic [2:0] flags);
|
output logic [2:0] flags);
|
||||||
|
|
||||||
logic [WIDTH-1:0] bbar, diff;
|
logic [WIDTH-1:0] bbar, diff;
|
||||||
logic carry, zero, neg, overflow, lt, ltu;
|
logic carry, eq, neg, overflow, lt, ltu;
|
||||||
|
|
||||||
// NOTE: This can be replaced by some faster logic optimized
|
// NOTE: This can be replaced by some faster logic optimized
|
||||||
// to just compute flags and not the difference.
|
// to just compute flags and not the difference.
|
||||||
@ -40,13 +40,13 @@ module comparator #(parameter WIDTH=32) (
|
|||||||
assign {carry, diff} = a + bbar + 1;
|
assign {carry, diff} = a + bbar + 1;
|
||||||
|
|
||||||
// condition code flags based on add/subtract output
|
// condition code flags based on add/subtract output
|
||||||
assign zero = (diff == 0);
|
assign eq = (diff == 0);
|
||||||
assign neg = diff[WIDTH-1];
|
assign neg = diff[WIDTH-1];
|
||||||
// overflow occurs when the numbers being subtracted have the opposite sign
|
// overflow occurs when the numbers being subtracted have the opposite sign
|
||||||
// and the result has the opposite sign fron the first
|
// and the result has the opposite sign fron the first
|
||||||
assign overflow = (a[WIDTH-1] ^ b[WIDTH-1]) & (a[WIDTH-1] ^ diff[WIDTH-1]);
|
assign overflow = (a[WIDTH-1] ^ b[WIDTH-1]) & (a[WIDTH-1] ^ diff[WIDTH-1]);
|
||||||
assign lt = neg ^ overflow;
|
assign lt = neg ^ overflow;
|
||||||
assign ltu = ~carry;
|
assign ltu = ~carry;
|
||||||
assign flags = {zero, lt, ltu};
|
assign flags = {eq, lt, ltu};
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ module controller(
|
|||||||
logic SubArithD;
|
logic SubArithD;
|
||||||
logic subD, sraD, sltD, sltuD;
|
logic subD, sraD, sltD, sltuD;
|
||||||
logic BranchTakenE;
|
logic BranchTakenE;
|
||||||
logic zeroE, ltE, ltuE;
|
logic eqE, ltE, ltuE;
|
||||||
logic unused;
|
logic unused;
|
||||||
logic BranchFlagE;
|
logic BranchFlagE;
|
||||||
logic IEURegWriteE;
|
logic IEURegWriteE;
|
||||||
@ -170,10 +170,10 @@ module controller(
|
|||||||
assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source?
|
assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source?
|
||||||
assign CSRWriteD = CSRReadD & !(CSRZeroSrcD && InstrD[13]); // Don't write if setting or clearing zeros
|
assign CSRWriteD = CSRReadD & !(CSRZeroSrcD && InstrD[13]); // Don't write if setting or clearing zeros
|
||||||
|
|
||||||
// ALU Decoding
|
// ALU Decoding is lazy, only using func7[5] to distinguish add/sub and srl/sra
|
||||||
assign sltD = (Funct3D == 3'b010);
|
assign sltD = (Funct3D == 3'b010);
|
||||||
assign sltuD = (Funct3D == 3'b011);
|
assign sltuD = (Funct3D == 3'b011);
|
||||||
assign subD = (Funct3D == 3'b000 & Funct7D[5] & OpD[5]);
|
assign subD = (Funct3D == 3'b000 & Funct7D[5] & OpD[5]); // OpD[5] needed to distinguish sub from addi
|
||||||
assign sraD = (Funct3D == 3'b101 & Funct7D[5]);
|
assign sraD = (Funct3D == 3'b101 & Funct7D[5]);
|
||||||
assign SubArithD = ALUOpD & (subD | sraD | sltD | sltuD); // TRUE for R-type subtracts and sra, slt, sltu
|
assign SubArithD = ALUOpD & (subD | sraD | sltD | sltuD); // TRUE for R-type subtracts and sra, slt, sltu
|
||||||
assign ALUControlD = {W64D, SubArithD, ALUOpD};
|
assign ALUControlD = {W64D, SubArithD, ALUOpD};
|
||||||
@ -202,15 +202,14 @@ module controller(
|
|||||||
{IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE});
|
{IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE});
|
||||||
|
|
||||||
// Branch Logic
|
// Branch Logic
|
||||||
assign {zeroE, ltE, ltuE} = FlagsE;
|
assign {eqE, ltE, ltuE} = FlagsE;
|
||||||
mux4 #(1) branchflagmux(zeroE, 1'b0, ltE, ltuE, Funct3E[2:1], BranchFlagE);
|
mux4 #(1) branchflagmux(eqE, 1'b0, ltE, ltuE, Funct3E[2:1], BranchFlagE);
|
||||||
assign BranchTakenE = BranchFlagE ^ Funct3E[0];
|
assign BranchTakenE = BranchFlagE ^ Funct3E[0];
|
||||||
|
|
||||||
assign PCSrcE = JumpE | BranchE & BranchTakenE;
|
assign PCSrcE = JumpE | BranchE & BranchTakenE;
|
||||||
|
|
||||||
|
// Other execute stage controller signals
|
||||||
assign MemReadE = MemRWE[1];
|
assign MemReadE = MemRWE[1];
|
||||||
assign SCE = (ResultSrcE == 3'b100);
|
assign SCE = (ResultSrcE == 3'b100);
|
||||||
|
|
||||||
assign RegWriteE = IEURegWriteE | FWriteIntE; // IRF register writes could come from IEU or FPU controllers
|
assign RegWriteE = IEURegWriteE | FWriteIntE; // IRF register writes could come from IEU or FPU controllers
|
||||||
|
|
||||||
// Memory stage pipeline control register
|
// Memory stage pipeline control register
|
||||||
|
@ -66,11 +66,11 @@ module datapath (
|
|||||||
|
|
||||||
// Fetch stage signals
|
// Fetch stage signals
|
||||||
// Decode stage signals
|
// Decode stage signals
|
||||||
logic [`XLEN-1:0] RD1D, RD2D;
|
logic [`XLEN-1:0] R1D, R2D;
|
||||||
logic [`XLEN-1:0] ExtImmD;
|
logic [`XLEN-1:0] ExtImmD;
|
||||||
logic [4:0] RdD;
|
logic [4:0] RdD;
|
||||||
// Execute stage signals
|
// Execute stage signals
|
||||||
logic [`XLEN-1:0] RD1E, RD2E;
|
logic [`XLEN-1:0] R1E, R2E;
|
||||||
logic [`XLEN-1:0] ExtImmE;
|
logic [`XLEN-1:0] ExtImmE;
|
||||||
|
|
||||||
// logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, SrcAE2, SrcBE2; // *** MAde forwardedsrcae an output to get rid of a mux in the critical path.
|
// logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, SrcAE2, SrcBE2; // *** MAde forwardedsrcae an output to get rid of a mux in the critical path.
|
||||||
@ -91,19 +91,19 @@ module datapath (
|
|||||||
assign Rs1D = InstrD[19:15];
|
assign Rs1D = InstrD[19:15];
|
||||||
assign Rs2D = InstrD[24:20];
|
assign Rs2D = InstrD[24:20];
|
||||||
assign RdD = InstrD[11:7];
|
assign RdD = InstrD[11:7];
|
||||||
regfile regf(clk, reset, RegWriteW, Rs1D, Rs2D, RdW, WriteDataW, RD1D, RD2D);
|
regfile regf(clk, reset, RegWriteW, Rs1D, Rs2D, RdW, WriteDataW, R1D, R2D);
|
||||||
extend ext(.InstrD(InstrD[31:7]), .ImmSrcD, .ExtImmD);
|
extend ext(.InstrD(InstrD[31:7]), .ImmSrcD, .ExtImmD);
|
||||||
|
|
||||||
// Execute stage pipeline register and logic
|
// Execute stage pipeline register and logic
|
||||||
flopenrc #(`XLEN) RD1EReg(clk, reset, FlushE, ~StallE, RD1D, RD1E);
|
flopenrc #(`XLEN) RD1EReg(clk, reset, FlushE, ~StallE, R1D, R1E);
|
||||||
flopenrc #(`XLEN) RD2EReg(clk, reset, FlushE, ~StallE, RD2D, RD2E);
|
flopenrc #(`XLEN) RD2EReg(clk, reset, FlushE, ~StallE, R2D, R2E);
|
||||||
flopenrc #(`XLEN) ExtImmEReg(clk, reset, FlushE, ~StallE, ExtImmD, ExtImmE);
|
flopenrc #(`XLEN) ExtImmEReg(clk, reset, FlushE, ~StallE, ExtImmD, ExtImmE);
|
||||||
flopenrc #(5) Rs1EReg(clk, reset, FlushE, ~StallE, Rs1D, Rs1E);
|
flopenrc #(5) Rs1EReg(clk, reset, FlushE, ~StallE, Rs1D, Rs1E);
|
||||||
flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E);
|
flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E);
|
||||||
flopenrc #(5) RdEReg(clk, reset, FlushE, ~StallE, RdD, RdE);
|
flopenrc #(5) RdEReg(clk, reset, FlushE, ~StallE, RdD, RdE);
|
||||||
|
|
||||||
mux3 #(`XLEN) faemux(RD1E, WriteDataW, ResultM, ForwardAE, ForwardedSrcAE);
|
mux3 #(`XLEN) faemux(R1E, WriteDataW, ResultM, ForwardAE, ForwardedSrcAE);
|
||||||
mux3 #(`XLEN) fbemux(RD2E, WriteDataW, ResultM, ForwardBE, ForwardedSrcBE);
|
mux3 #(`XLEN) fbemux(R2E, WriteDataW, ResultM, ForwardBE, ForwardedSrcBE);
|
||||||
comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, FlagsE);
|
comparator #(`XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, FlagsE);
|
||||||
mux2 #(`XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE);
|
mux2 #(`XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE);
|
||||||
mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ExtImmE, ALUSrcBE, SrcBE);
|
mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ExtImmE, ALUSrcBE, SrcBE);
|
||||||
|
@ -26,10 +26,10 @@
|
|||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
module shifter (
|
module shifter (
|
||||||
input logic [`XLEN-1:0] a,
|
input logic [`XLEN-1:0] A,
|
||||||
input logic [`LOG_XLEN-1:0] amt,
|
input logic [`LOG_XLEN-1:0] Amt,
|
||||||
input logic right, arith, w64,
|
input logic Right, Arith, W64,
|
||||||
output logic [`XLEN-1:0] y);
|
output logic [`XLEN-1:0] Y);
|
||||||
|
|
||||||
logic [2*`XLEN-2:0] z, zshift;
|
logic [2*`XLEN-2:0] z, zshift;
|
||||||
logic [`LOG_XLEN-1:0] amttrunc, offset;
|
logic [`LOG_XLEN-1:0] amttrunc, offset;
|
||||||
@ -42,34 +42,34 @@ module shifter (
|
|||||||
generate
|
generate
|
||||||
if (`XLEN==32) begin:shifter // RV32
|
if (`XLEN==32) begin:shifter // RV32
|
||||||
always_comb // funnel mux
|
always_comb // funnel mux
|
||||||
if (right)
|
if (Right)
|
||||||
if (arith) z = {{31{a[31]}}, a};
|
if (Arith) z = {{31{A[31]}}, A};
|
||||||
else z = {31'b0, a};
|
else z = {31'b0, A};
|
||||||
else z = {a, 31'b0};
|
else z = {A, 31'b0};
|
||||||
assign amttrunc = amt; // shift amount
|
assign amttrunc = Amt; // shift amount
|
||||||
end else begin:shifter // RV64
|
end else begin:shifter // RV64
|
||||||
always_comb // funnel mux
|
always_comb // funnel mux
|
||||||
if (w64) begin // 32-bit shifts
|
if (W64) begin // 32-bit shifts
|
||||||
if (right)
|
if (Right)
|
||||||
if (arith) z = {64'b0, {31{a[31]}}, a[31:0]};
|
if (Arith) z = {64'b0, {31{A[31]}}, A[31:0]};
|
||||||
else z = {95'b0, a[31:0]};
|
else z = {95'b0, A[31:0]};
|
||||||
else z = {32'b0, a[31:0], 63'b0};
|
else z = {32'b0, A[31:0], 63'b0};
|
||||||
end else begin
|
end else begin
|
||||||
if (right)
|
if (Right)
|
||||||
if (arith) z = {{63{a[63]}}, a};
|
if (Arith) z = {{63{A[63]}}, A};
|
||||||
else z = {63'b0, a};
|
else z = {63'b0, A};
|
||||||
else z = {a, 63'b0};
|
else z = {A, 63'b0};
|
||||||
end
|
end
|
||||||
assign amttrunc = w64 ? {1'b0, amt[4:0]} : amt; // 32 or 64-bit shift
|
assign amttrunc = W64 ? {1'b0, Amt[4:0]} : Amt; // 32 or 64-bit shift
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
// opposite offset for right shfits
|
// opposite offset for right shfits
|
||||||
assign offset = right ? amttrunc : ~amttrunc;
|
assign offset = Right ? amttrunc : ~amttrunc;
|
||||||
|
|
||||||
// funnel operation
|
// funnel operation
|
||||||
assign zshift = z >> offset;
|
assign zshift = z >> offset;
|
||||||
assign y = zshift[`XLEN-1:0];
|
assign Y = zshift[`XLEN-1:0];
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user