diff --git a/pipelined/regression/sim-wally-batch b/pipelined/regression/sim-wally-batch index 8b5b5d62..7afcadb2 100755 --- a/pipelined/regression/sim-wally-batch +++ b/pipelined/regression/sim-wally-batch @@ -1 +1 @@ -vsim -c -do "do wally-pipelined-batch.do rv32gc wally32periph" +vsim -c -do "do wally-pipelined-batch.do rv64gc arch64d" diff --git a/pipelined/src/fpu/fma.sv b/pipelined/src/fpu/fma.sv index 067147ee..fcf209f6 100644 --- a/pipelined/src/fpu/fma.sv +++ b/pipelined/src/fpu/fma.sv @@ -1,7 +1,7 @@ /////////////////////////////////////////// // -// Written: me@KatherineParry.com, David Harris -// Modified: 6/23/2021 +// Written: 6/23/2021 me@KatherineParry.com, David_Harris@hmc.edu +// Modified: // // Purpose: Floating point multiply-accumulate of configurable size // @@ -63,18 +63,18 @@ module fma( // calculate the product's exponent - expadd expadd(.Fmt, .Xe, .Ye, .XZero, .YZero, .Pe); + fmaexpadd expadd(.Fmt, .Xe, .Ye, .XZero, .YZero, .Pe); // multiplication of the mantissa's - mult mult(.Xm, .Ym, .Pm); + fmamult mult(.Xm, .Ym, .Pm); /////////////////////////////////////////////////////////////////////////////// // Alignment shifter /////////////////////////////////////////////////////////////////////////////// // calculate the signs and take the opperation into account - sign sign(.OpCtrl, .Xs, .Ys, .Zs, .Ps, .As); + fmasign sign(.OpCtrl, .Xs, .Ys, .Zs, .Ps, .As); - align align(.Ze, .Zm, .XZero, .YZero, .ZZero, .Xe, .Ye, + fmaalign align(.Ze, .Zm, .XZero, .YZero, .ZZero, .Xe, .Ye, .Am, .ZmSticky, .KillProd); @@ -83,223 +83,8 @@ module fma( // // Addition/LZA // /////////////////////////////////////////////////////////////////////////////// - add add(.Am, .Pm, .Ze, .Pe, .Ps, .As, .KillProd, .ZmSticky, .AmInv, .PmKilled, .NegSum, .InvA, .Sm, .Se, .Ss); + fmaadd add(.Am, .Pm, .Ze, .Pe, .Ps, .As, .KillProd, .ZmSticky, .AmInv, .PmKilled, .NegSum, .InvA, .Sm, .Se, .Ss); - loa loa(.A(AmInv+{(3*`NF+6)'(0),InvA&~((ZmSticky&~KillProd))}), .P({PmKilled, 1'b0, InvA&Ps&ZmSticky&KillProd}), .SCnt); + fmalza lza(.A(AmInv+{(3*`NF+6)'(0),InvA&~((ZmSticky&~KillProd))}), .P({PmKilled, 1'b0, InvA&Ps&ZmSticky&KillProd}), .SCnt); endmodule - -module expadd( - input logic [`FMTBITS-1:0] Fmt, // format of the output: single double half quad - input logic [`NE-1:0] Xe, Ye, // input's exponents - input logic XZero, YZero, // are the inputs zero - 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 Pe = ({2'b0, Xe} + {2'b0, Ye} - {2'b0, (`NE)'(`BIAS)})&{`NE+2{~(XZero|YZero)}}; - -endmodule - - - - - -module mult( - input logic [`NF:0] Xm, Ym, - output logic [2*`NF+1:0] Pm -); - assign Pm = Xm * Ym; -endmodule - - - - - - - - -module sign( - input logic [2:0] OpCtrl, // opperation contol - input logic Xs, Ys, Zs, // sign of the inputs - output logic Ps, // the product's sign - takes opperation into account - output logic As // aligned addend sign used in fma - takes opperation into account -); - - // Calculate the product's sign - // Negate product's sign if FNMADD or FNMSUB - - // flip is negation opperation - assign Ps = Xs ^ Ys ^ (OpCtrl[1]&~OpCtrl[2]); - // flip if subtraction - assign As = Zs^OpCtrl[0]; - -endmodule - - - - - - - - -module align( - input logic [`NE-1:0] Xe, Ye, Ze, // biased exponents in B(NE.0) format - input logic [`NF:0] Zm, // significand in U(0.NF) format] - input logic XZero, YZero, ZZero, // is the input zero - output logic [3*`NF+5:0] Am, // addend aligned for addition in U(NF+5.2NF+1) - output logic ZmSticky, // Sticky bit calculated from the aliged addend - output logic KillProd // should the product be set to zero -); - - logic [`NE+1:0] ACnt; // how far to shift the addend to align with the product in Q(NE+2.0) format - logic [4*`NF+5:0] ZmShifted; // output of the alignment shifter including sticky bits U(NF+5.3NF+1) - logic [4*`NF+5:0] ZmPreshifted; // input to the alignment shifter U(NF+5.3NF+1) - logic KillZ; - - /////////////////////////////////////////////////////////////////////////////// - // Alignment shifter - /////////////////////////////////////////////////////////////////////////////// - - // 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 Pe, but ACnt is on the critical path so we replicate logic for speed - assign ACnt = {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 ZmPreshifted = {Zm,(3*`NF+5)'(0)}; - - assign KillProd = (ACnt[`NE+1]&~ZZero)|XZero|YZero; - assign KillZ = $signed(ACnt)>$signed((`NE+2)'(3)*(`NE+2)'(`NF)+(`NE+2)'(5)); - - always_comb - begin - - // If the product is too small to effect the sum, kill the product - - // | 54'b0 | 106'b(product) | 2'b0 | - // | addnend | - if (KillProd) begin - ZmShifted = {(`NF+3)'(0), Zm, (2*`NF+2)'(0)}; - ZmSticky = ~(XZero|YZero); - - // 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 if (KillZ) begin - ZmShifted = 0; - ZmSticky = ~ZZero; - - // If the Addend is shifted right - // | 54'b0 | 106'b(product) | 2'b0 | - // | addnend | - end else begin - ZmShifted = ZmPreshifted >> ACnt; - ZmSticky = |(ZmShifted[`NF-1:0]); - - end - end - - assign Am = ZmShifted[4*`NF+5:`NF]; - -endmodule - - - - - - - -module add( - input logic [3*`NF+5:0] Am, // aligned addend's mantissa for addition in U(NF+5.2NF+1) - input logic [2*`NF+1:0] Pm, // the product's mantissa - input logic Ps, As,// the product sign and the alligend addeded's sign (Modified Z sign for other opperations) - input logic KillProd, // should the product be set to 0 - input logic ZmSticky, - input logic [`NE-1:0] Ze, - input logic [`NE+1:0] Pe, - 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 NegSum, // was the sum negitive - output logic InvA, // do you invert the aligned addend - output logic Ss, - output logic [`NE+1:0] Se, - output logic [3*`NF+5:0] Sm // the positive sum -); - logic [3*`NF+6:0] PreSum, NegPreSum; // possibly negitive sum - - /////////////////////////////////////////////////////////////////////////////// - // Addition - /////////////////////////////////////////////////////////////////////////////// - - // Negate Z when doing one of the following opperations: - // -prod + Z - // prod - Z - assign InvA = As ^ Ps; - - // Choose an inverted or non-inverted addend - the one has to be added now for the LZA - 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 PmKilled = Pm&{2*`NF+2{~KillProd}}; - // Do the addition - // - calculate a positive and negitive sum in parallel - // Zsticky Psticky - // PreSum -1 = don't add 1 +1 = add 2 - // NegPreSum +1 = add 2 -1 = don't add 1 - // for NegPreSum the product is set to -1 whenever the product is killed, therefore add 1, 2 or 0 - assign PreSum = {{`NF+3{1'b0}}, PmKilled, 1'b0, InvA&ZmSticky&KillProd} + AmInv + {{3*`NF+6{1'b0}}, InvA&~((ZmSticky&~KillProd))}; - assign NegPreSum = {1'b0, Am} + {{`NF+3{1'b1}}, ~PmKilled, 2'b11} + {(3*`NF+5)'(0), ZmSticky&~KillProd, ~(ZmSticky)}; - - // Is the sum negitive - assign NegSum = PreSum[3*`NF+6]; - - // Choose the positive sum and accompanying LZA result. - assign Sm = NegSum ? NegPreSum[3*`NF+5:0] : PreSum[3*`NF+5:0]; - // is the result negitive - // if p - z is the Sum negitive - // if -p + z is the Sum positive - // if -p - z then the Sum is negitive - assign Ss = NegSum^Ps; //*** move to execute stage - assign Se = KillProd ? {2'b0, Ze} : Pe; -endmodule - - -module loa( // [Schmookler & Nowka, Leading zero anticipation and detection, IEEE Sym. Computer Arithmetic, 2001] - input logic [3*`NF+6:0] A, // addend - input logic [2*`NF+3:0] P, // product - output logic [$clog2(3*`NF+7)-1:0] SCnt // normalization shift count for the positive result - ); - - logic [3*`NF+6:0] T; - logic [3*`NF+6:0] G; - logic [3*`NF+6:0] Z; - logic [3*`NF+6:0] f; - - assign T[3*`NF+6:2*`NF+4] = A[3*`NF+6:2*`NF+4]; - assign G[3*`NF+6:2*`NF+4] = 0; - assign Z[3*`NF+6:2*`NF+4] = ~A[3*`NF+6:2*`NF+4]; - assign T[2*`NF+3:0] = A[2*`NF+3:0]^P; - assign G[2*`NF+3:0] = A[2*`NF+3:0]&P; - assign Z[2*`NF+3:0] = ~A[2*`NF+3:0]&~P; - - - // 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])) - 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 #(3*`NF+7) lzc (.num(f), .ZeroCnt(SCnt)); - -endmodule diff --git a/pipelined/src/fpu/fmaadd.sv b/pipelined/src/fpu/fmaadd.sv new file mode 100644 index 00000000..4b52208c --- /dev/null +++ b/pipelined/src/fpu/fmaadd.sv @@ -0,0 +1,83 @@ +/////////////////////////////////////////// +// +// Written: 6/23/2021 me@KatherineParry.com, David_Harris@hmc.edu +// Modified: +// +// Purpose: FMA significand adder +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. +//////////////////////////////////////////////////////////////////////////////////////////////// + +`include "wally-config.vh" + +module fmaadd( + input logic [3*`NF+5:0] Am, // aligned addend's mantissa for addition in U(NF+5.2NF+1) + input logic [2*`NF+1:0] Pm, // the product's mantissa + input logic Ps, As,// the product sign and the alligend addeded's sign (Modified Z sign for other opperations) + input logic KillProd, // should the product be set to 0 + input logic ZmSticky, + input logic [`NE-1:0] Ze, + input logic [`NE+1:0] Pe, + 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 NegSum, // was the sum negitive + output logic InvA, // do you invert the aligned addend + output logic Ss, + output logic [`NE+1:0] Se, + output logic [3*`NF+5:0] Sm // the positive sum +); + logic [3*`NF+6:0] PreSum, NegPreSum; // possibly negitive sum + + /////////////////////////////////////////////////////////////////////////////// + // Addition + /////////////////////////////////////////////////////////////////////////////// + + // Negate Z when doing one of the following opperations: + // -prod + Z + // prod - Z + assign InvA = As ^ Ps; + + // Choose an inverted or non-inverted addend - the one has to be added now for the LZA + 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 PmKilled = Pm&{2*`NF+2{~KillProd}}; + // Do the addition + // - calculate a positive and negitive sum in parallel + // Zsticky Psticky + // PreSum -1 = don't add 1 +1 = add 2 + // NegPreSum +1 = add 2 -1 = don't add 1 + // for NegPreSum the product is set to -1 whenever the product is killed, therefore add 1, 2 or 0 + assign PreSum = {{`NF+3{1'b0}}, PmKilled, 1'b0, InvA&ZmSticky&KillProd} + AmInv + {{3*`NF+6{1'b0}}, InvA&~((ZmSticky&~KillProd))}; + assign NegPreSum = {1'b0, Am} + {{`NF+3{1'b1}}, ~PmKilled, 2'b11} + {(3*`NF+5)'(0), ZmSticky&~KillProd, ~(ZmSticky)}; + + // Is the sum negitive + assign NegSum = PreSum[3*`NF+6]; + + // Choose the positive sum and accompanying LZA result. + assign Sm = NegSum ? NegPreSum[3*`NF+5:0] : PreSum[3*`NF+5:0]; + // is the result negitive + // if p - z is the Sum negitive + // if -p + z is the Sum positive + // if -p - z then the Sum is negitive + assign Ss = NegSum^Ps; //*** move to execute stage + assign Se = KillProd ? {2'b0, Ze} : Pe; +endmodule diff --git a/pipelined/src/fpu/fmaalign.sv b/pipelined/src/fpu/fmaalign.sv new file mode 100644 index 00000000..f7c84999 --- /dev/null +++ b/pipelined/src/fpu/fmaalign.sv @@ -0,0 +1,101 @@ + +/////////////////////////////////////////// +// +// Written: 6/23/2021 me@KatherineParry.com, David_Harris@hmc.edu +// Modified: +// +// Purpose: FMA alginment shift +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. +//////////////////////////////////////////////////////////////////////////////////////////////// + +`include "wally-config.vh" + +module fmaalign( + input logic [`NE-1:0] Xe, Ye, Ze, // biased exponents in B(NE.0) format + input logic [`NF:0] Zm, // significand in U(0.NF) format] + input logic XZero, YZero, ZZero, // is the input zero + output logic [3*`NF+5:0] Am, // addend aligned for addition in U(NF+5.2NF+1) + output logic ZmSticky, // Sticky bit calculated from the aliged addend + output logic KillProd // should the product be set to zero +); + + logic [`NE+1:0] ACnt; // how far to shift the addend to align with the product in Q(NE+2.0) format + logic [4*`NF+5:0] ZmShifted; // output of the alignment shifter including sticky bits U(NF+5.3NF+1) + logic [4*`NF+5:0] ZmPreshifted; // input to the alignment shifter U(NF+5.3NF+1) + logic KillZ; + + /////////////////////////////////////////////////////////////////////////////// + // Alignment shifter + /////////////////////////////////////////////////////////////////////////////// + + // 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 Pe, but ACnt is on the critical path so we replicate logic for speed + assign ACnt = {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 ZmPreshifted = {Zm,(3*`NF+5)'(0)}; + + assign KillProd = (ACnt[`NE+1]&~ZZero)|XZero|YZero; + assign KillZ = $signed(ACnt)>$signed((`NE+2)'(3)*(`NE+2)'(`NF)+(`NE+2)'(5)); + + always_comb + begin + + // If the product is too small to effect the sum, kill the product + + // | 54'b0 | 106'b(product) | 2'b0 | + // | addnend | + if (KillProd) begin + ZmShifted = {(`NF+3)'(0), Zm, (2*`NF+2)'(0)}; + ZmSticky = ~(XZero|YZero); + + // 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 if (KillZ) begin + ZmShifted = 0; + ZmSticky = ~ZZero; + + // If the Addend is shifted right + // | 54'b0 | 106'b(product) | 2'b0 | + // | addnend | + end else begin + ZmShifted = ZmPreshifted >> ACnt; + ZmSticky = |(ZmShifted[`NF-1:0]); + + end + end + + assign Am = ZmShifted[4*`NF+5:`NF]; + +endmodule + diff --git a/pipelined/src/fpu/fmaexpadd.sv b/pipelined/src/fpu/fmaexpadd.sv new file mode 100644 index 00000000..1d208327 --- /dev/null +++ b/pipelined/src/fpu/fmaexpadd.sv @@ -0,0 +1,42 @@ +/////////////////////////////////////////// +// +// Written: 6/23/2021 me@KatherineParry.com, David_Harris@hmc.edu +// Modified: +// +// Purpose: FMA exponent addition +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. +//////////////////////////////////////////////////////////////////////////////////////////////// + +`include "wally-config.vh" + +module fmaexpadd( + input logic [`FMTBITS-1:0] Fmt, // format of the output: single double half quad + input logic [`NE-1:0] Xe, Ye, // input's exponents + input logic XZero, YZero, // are the inputs zero + 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 Pe = ({2'b0, Xe} + {2'b0, Ye} - {2'b0, (`NE)'(`BIAS)})&{`NE+2{~(XZero|YZero)}}; + +endmodule \ No newline at end of file diff --git a/pipelined/src/fpu/fmalza.sv b/pipelined/src/fpu/fmalza.sv new file mode 100644 index 00000000..3baaf2a0 --- /dev/null +++ b/pipelined/src/fpu/fmalza.sv @@ -0,0 +1,62 @@ +/////////////////////////////////////////// +// +// Written: 6/23/2021 me@KatherineParry.com, David_Harris@hmc.edu +// Modified: +// +// Purpose: Leading Zero Anticipator +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. +//////////////////////////////////////////////////////////////////////////////////////////////// + +`include "wally-config.vh" + +module fmalza( // [Schmookler & Nowka, Leading zero anticipation and detection, IEEE Sym. Computer Arithmetic, 2001] + input logic [3*`NF+6:0] A, // addend + input logic [2*`NF+3:0] P, // product + output logic [$clog2(3*`NF+7)-1:0] SCnt // normalization shift count for the positive result + ); + + logic [3*`NF+6:0] T; + logic [3*`NF+6:0] G; + logic [3*`NF+6:0] Z; + logic [3*`NF+6:0] f; + + assign T[3*`NF+6:2*`NF+4] = A[3*`NF+6:2*`NF+4]; + assign G[3*`NF+6:2*`NF+4] = 0; + assign Z[3*`NF+6:2*`NF+4] = ~A[3*`NF+6:2*`NF+4]; + assign T[2*`NF+3:0] = A[2*`NF+3:0]^P; + assign G[2*`NF+3:0] = A[2*`NF+3:0]&P; + assign Z[2*`NF+3:0] = ~A[2*`NF+3:0]&~P; + + + // 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])) + 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 #(3*`NF+7) lzc (.num(f), .ZeroCnt(SCnt)); + +endmodule diff --git a/pipelined/src/fpu/fmamult.sv b/pipelined/src/fpu/fmamult.sv new file mode 100644 index 00000000..1e1b0981 --- /dev/null +++ b/pipelined/src/fpu/fmamult.sv @@ -0,0 +1,38 @@ +/////////////////////////////////////////// +// +// Written: 6/23/2021 me@KatherineParry.com, David_Harris@hmc.edu +// Modified: +// +// Purpose: FMA Significand Multiplier +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. +//////////////////////////////////////////////////////////////////////////////////////////////// + +`include "wally-config.vh" + +module fmamult( + input logic [`NF:0] Xm, Ym, + output logic [2*`NF+1:0] Pm +); + assign Pm = Xm * Ym; +endmodule + diff --git a/pipelined/src/fpu/fmasign.sv b/pipelined/src/fpu/fmasign.sv new file mode 100644 index 00000000..66c1af83 --- /dev/null +++ b/pipelined/src/fpu/fmasign.sv @@ -0,0 +1,47 @@ +/////////////////////////////////////////// +// +// Written: 6/23/2021 me@KatherineParry.com, David_Harris@hmc.edu +// Modified: +// +// Purpose: FMA Sign Logic +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// MIT LICENSE +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. +//////////////////////////////////////////////////////////////////////////////////////////////// + +`include "wally-config.vh" + +module fmasign( + input logic [2:0] OpCtrl, // opperation contol + input logic Xs, Ys, Zs, // sign of the inputs + output logic Ps, // the product's sign - takes opperation into account + output logic As // aligned addend sign used in fma - takes opperation into account +); + + // Calculate the product's sign + // Negate product's sign if FNMADD or FNMSUB + + // flip is negation opperation + assign Ps = Xs ^ Ys ^ (OpCtrl[1]&~OpCtrl[2]); + // flip if subtraction + assign As = Zs^OpCtrl[0]; + +endmodule diff --git a/pipelined/testbench/tests.vh b/pipelined/testbench/tests.vh index 587733c3..fe3bd62f 100644 --- a/pipelined/testbench/tests.vh +++ b/pipelined/testbench/tests.vh @@ -1902,7 +1902,8 @@ string imperas32f[] = '{ "rv32i_m/privilege/src/WALLY-gpio-01.S", "rv32i_m/privilege/src/WALLY-clint-01.S", "rv32i_m/privilege/src/WALLY-uart-01.S", - "rv32i_m/privilege/src/WALLY-plic-01.S" + "rv32i_m/privilege/src/WALLY-plic-01.S", + "rv32i_m/privilege/src/WALLY-plic-s-01.S" };