mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
unpack.sv cleanup
This commit is contained in:
parent
2042374102
commit
c3c764a171
@ -175,7 +175,7 @@ module fpu (
|
|||||||
// unpack unit
|
// unpack unit
|
||||||
// - splits FP inputs into their various parts
|
// - splits FP inputs into their various parts
|
||||||
// - does some classifications (SNaN, NaN, Denorm, Norm, Zero, Infifnity)
|
// - does some classifications (SNaN, NaN, Denorm, Norm, Zero, Infifnity)
|
||||||
unpack unpack (.X(FSrcXE), .Y(FSrcYE), .Z(FSrcZE), .FOpCtrlE, .FmtE,
|
unpack unpack (.X(FSrcXE), .Y(FSrcYE), .Z(FSrcZE), .FmtE,
|
||||||
.XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, .XManE, .YManE, .ZManE,
|
.XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, .XManE, .YManE, .ZManE,
|
||||||
.XNaNE, .YNaNE, .ZNaNE, .XSNaNE, .YSNaNE, .ZSNaNE, .XDenormE, .YDenormE, .ZDenormE,
|
.XNaNE, .YNaNE, .ZNaNE, .XSNaNE, .YSNaNE, .ZSNaNE, .XDenormE, .YDenormE, .ZDenormE,
|
||||||
.XZeroE, .YZeroE, .ZZeroE, .XInfE, .YInfE, .ZInfE, .XExpMaxE, .XNormE);
|
.XZeroE, .YZeroE, .ZZeroE, .XInfE, .YInfE, .ZInfE, .XExpMaxE, .XNormE);
|
||||||
|
@ -1,58 +1,83 @@
|
|||||||
`include "wally-config.vh"
|
`include "wally-config.vh"
|
||||||
|
|
||||||
module unpack (
|
module unpack (
|
||||||
input logic [`FLEN-1:0] X, Y, Z,
|
input logic [`FLEN-1:0] X, Y, Z, // inputs from register file
|
||||||
input logic [`FPSIZES/3:0] FmtE,
|
input logic [`FPSIZES/3:0] FmtE, // format signal 00 - single 10 - double 11 - quad 10 - half
|
||||||
input logic [2:0] FOpCtrlE,
|
output logic XSgnE, YSgnE, ZSgnE, // sign bits of XYZ
|
||||||
output logic XSgnE, YSgnE, ZSgnE,
|
output logic [`NE-1:0] XExpE, YExpE, ZExpE, // exponents of XYZ (converted to largest supported precision)
|
||||||
output logic [`NE-1:0] XExpE, YExpE, ZExpE,
|
output logic [`NF:0] XManE, YManE, ZManE, // mantissas of XYZ (converted to largest supported precision)
|
||||||
output logic [`NF:0] XManE, YManE, ZManE,
|
output logic XNormE, // is X a normalized number
|
||||||
output logic XNormE,
|
output logic XNaNE, YNaNE, ZNaNE, // is XYZ a NaN
|
||||||
output logic XNaNE, YNaNE, ZNaNE,
|
output logic XSNaNE, YSNaNE, ZSNaNE, // is XYZ a signaling NaN
|
||||||
output logic XSNaNE, YSNaNE, ZSNaNE,
|
output logic XDenormE, YDenormE, ZDenormE, // is XYZ denormalized
|
||||||
output logic XDenormE, YDenormE, ZDenormE,
|
output logic XZeroE, YZeroE, ZZeroE, // is XYZ zero
|
||||||
output logic XZeroE, YZeroE, ZZeroE,
|
output logic XInfE, YInfE, ZInfE, // is XYZ infinity
|
||||||
output logic XInfE, YInfE, ZInfE,
|
output logic XExpMaxE // does X have the maximum exponent (NaN or Inf)
|
||||||
output logic XExpMaxE
|
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [`NF-1:0] XFracE, YFracE, ZFracE;
|
logic [`NF-1:0] XFracE, YFracE, ZFracE; //Fraction of XYZ
|
||||||
logic XExpNonzero, YExpNonzero, ZExpNonzero;
|
logic XExpNonzero, YExpNonzero, ZExpNonzero; // is the exponent of XYZ non-zero
|
||||||
logic XFracZero, YFracZero, ZFracZero; // input fraction zero
|
logic XFracZero, YFracZero, ZFracZero; // is the fraction zero
|
||||||
logic XExpZero, YExpZero, ZExpZero; // input exponent zero
|
logic XExpZero, YExpZero, ZExpZero; // is the exponent zero
|
||||||
logic YExpMaxE, ZExpMaxE; // input exponent all 1s
|
logic YExpMaxE, ZExpMaxE; // is the exponent all 1s
|
||||||
|
|
||||||
if (`FPSIZES == 1) begin
|
if (`FPSIZES == 1) begin // if there is only one floating point format supported
|
||||||
|
|
||||||
|
// sign bit
|
||||||
assign XSgnE = X[`FLEN-1];
|
assign XSgnE = X[`FLEN-1];
|
||||||
assign YSgnE = Y[`FLEN-1];
|
assign YSgnE = Y[`FLEN-1];
|
||||||
assign ZSgnE = Z[`FLEN-1];
|
assign ZSgnE = Z[`FLEN-1];
|
||||||
|
|
||||||
|
// exponent
|
||||||
assign XExpE = X[`FLEN-2:`NF];
|
assign XExpE = X[`FLEN-2:`NF];
|
||||||
assign YExpE = Y[`FLEN-2:`NF];
|
assign YExpE = Y[`FLEN-2:`NF];
|
||||||
assign ZExpE = Z[`FLEN-2:`NF];
|
assign ZExpE = Z[`FLEN-2:`NF];
|
||||||
|
|
||||||
|
// fraction (no assumed 1)
|
||||||
assign XFracE = X[`NF-1:0];
|
assign XFracE = X[`NF-1:0];
|
||||||
assign YFracE = Y[`NF-1:0];
|
assign YFracE = Y[`NF-1:0];
|
||||||
assign ZFracE = Z[`NF-1:0];
|
assign ZFracE = Z[`NF-1:0];
|
||||||
|
|
||||||
|
// is the exponent non-zero
|
||||||
assign XExpNonzero = |XExpE;
|
assign XExpNonzero = |XExpE;
|
||||||
assign YExpNonzero = |YExpE;
|
assign YExpNonzero = |YExpE;
|
||||||
assign ZExpNonzero = |ZExpE;
|
assign ZExpNonzero = |ZExpE;
|
||||||
|
|
||||||
|
// is the exponent all 1's
|
||||||
assign XExpMaxE = &XExpE;
|
assign XExpMaxE = &XExpE;
|
||||||
assign YExpMaxE = &YExpE;
|
assign YExpMaxE = &YExpE;
|
||||||
assign ZExpMaxE = &ZExpE;
|
assign ZExpMaxE = &ZExpE;
|
||||||
|
|
||||||
|
|
||||||
end else if (`FPSIZES == 2) begin
|
end else if (`FPSIZES == 2) begin // if there are 2 floating point formats supported
|
||||||
|
|
||||||
logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Bottom half or NaN, if not properly NaN boxed
|
//***need better names for these constants
|
||||||
|
// largest format | smaller format
|
||||||
|
//----------------------------------
|
||||||
|
// `FLEN | `LEN1 length of floating point number
|
||||||
|
// `NE | `NE1 length of exponent
|
||||||
|
// `NF | `NF1 length of fraction
|
||||||
|
// `BIAS | `BIAS1 exponent's bias value
|
||||||
|
// `FMT | `FMT1 precision's format value - Q=11 D=01 S=00 H=10
|
||||||
|
|
||||||
|
// Possible combinantions specified by spec:
|
||||||
|
// double and single
|
||||||
|
// single and half
|
||||||
|
|
||||||
|
// Not needed but can also handle:
|
||||||
|
// quad and double
|
||||||
|
// quad and single
|
||||||
|
// quad and half
|
||||||
|
// double and half
|
||||||
|
|
||||||
|
logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Remove NaN boxing or NaN, if not properly NaN boxed
|
||||||
|
|
||||||
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN
|
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN
|
||||||
assign XLen1 = &X[`FLEN-1:`LEN1] ? X[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
assign XLen1 = &X[`FLEN-1:`LEN1] ? X[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
||||||
assign YLen1 = &Y[`FLEN-1:`LEN1] ? Y[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
assign YLen1 = &Y[`FLEN-1:`LEN1] ? Y[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
||||||
assign ZLen1 = &Z[`FLEN-1:`LEN1] ? Z[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
assign ZLen1 = &Z[`FLEN-1:`LEN1] ? Z[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
||||||
|
|
||||||
|
// choose sign bit depending on format - 1=larger precsion 0=smaller precision
|
||||||
assign XSgnE = FmtE ? X[`FLEN-1] : XLen1[`LEN1-1];
|
assign XSgnE = FmtE ? X[`FLEN-1] : XLen1[`LEN1-1];
|
||||||
assign YSgnE = FmtE ? Y[`FLEN-1] : YLen1[`LEN1-1];
|
assign YSgnE = FmtE ? Y[`FLEN-1] : YLen1[`LEN1-1];
|
||||||
assign ZSgnE = FmtE ? Z[`FLEN-1] : ZLen1[`LEN1-1];
|
assign ZSgnE = FmtE ? Z[`FLEN-1] : ZLen1[`LEN1-1];
|
||||||
@ -64,63 +89,94 @@ module unpack (
|
|||||||
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
||||||
// dexp = 0bdd dbbb bbbb
|
// dexp = 0bdd dbbb bbbb
|
||||||
// also need to take into account possible zero/denorm/inf/NaN values
|
// also need to take into account possible zero/denorm/inf/NaN values
|
||||||
|
|
||||||
|
// extract the exponent, converting the smaller exponent into the larger precision if nessisary
|
||||||
assign XExpE = FmtE ? X[`FLEN-2:`NF] : {XLen1[`LEN1-2], {`NE-`NE1{~XLen1[`LEN1-2]&~XExpZero|XExpMaxE}}, XLen1[`LEN1-3:`NF1]};
|
assign XExpE = FmtE ? X[`FLEN-2:`NF] : {XLen1[`LEN1-2], {`NE-`NE1{~XLen1[`LEN1-2]&~XExpZero|XExpMaxE}}, XLen1[`LEN1-3:`NF1]};
|
||||||
assign YExpE = FmtE ? Y[`FLEN-2:`NF] : {YLen1[`LEN1-2], {`NE-`NE1{~YLen1[`LEN1-2]&~YExpZero|YExpMaxE}}, YLen1[`LEN1-3:`NF1]};
|
assign YExpE = FmtE ? Y[`FLEN-2:`NF] : {YLen1[`LEN1-2], {`NE-`NE1{~YLen1[`LEN1-2]&~YExpZero|YExpMaxE}}, YLen1[`LEN1-3:`NF1]};
|
||||||
assign ZExpE = FmtE ? Z[`FLEN-2:`NF] : {ZLen1[`LEN1-2], {`NE-`NE1{~ZLen1[`LEN1-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`LEN1-3:`NF1]};
|
assign ZExpE = FmtE ? Z[`FLEN-2:`NF] : {ZLen1[`LEN1-2], {`NE-`NE1{~ZLen1[`LEN1-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`LEN1-3:`NF1]};
|
||||||
|
|
||||||
|
// extract the fraction, add trailing zeroes to the mantissa if nessisary
|
||||||
assign XFracE = FmtE ? X[`NF-1:0] : {XLen1[`NF1-1:0], (`NF-`NF1)'(0)};
|
assign XFracE = FmtE ? X[`NF-1:0] : {XLen1[`NF1-1:0], (`NF-`NF1)'(0)};
|
||||||
assign YFracE = FmtE ? Y[`NF-1:0] : {YLen1[`NF1-1:0], (`NF-`NF1)'(0)};
|
assign YFracE = FmtE ? Y[`NF-1:0] : {YLen1[`NF1-1:0], (`NF-`NF1)'(0)};
|
||||||
assign ZFracE = FmtE ? Z[`NF-1:0] : {ZLen1[`NF1-1:0], (`NF-`NF1)'(0)};
|
assign ZFracE = FmtE ? Z[`NF-1:0] : {ZLen1[`NF1-1:0], (`NF-`NF1)'(0)};
|
||||||
|
|
||||||
|
// is the exponent non-zero
|
||||||
assign XExpNonzero = FmtE ? |X[`FLEN-2:`NF] : |XLen1[`LEN1-2:`NF1];
|
assign XExpNonzero = FmtE ? |X[`FLEN-2:`NF] : |XLen1[`LEN1-2:`NF1];
|
||||||
assign YExpNonzero = FmtE ? |Y[`FLEN-2:`NF] : |YLen1[`LEN1-2:`NF1];
|
assign YExpNonzero = FmtE ? |Y[`FLEN-2:`NF] : |YLen1[`LEN1-2:`NF1];
|
||||||
assign ZExpNonzero = FmtE ? |Z[`FLEN-2:`NF] : |ZLen1[`LEN1-2:`NF1];
|
assign ZExpNonzero = FmtE ? |Z[`FLEN-2:`NF] : |ZLen1[`LEN1-2:`NF1];
|
||||||
|
|
||||||
|
// is the exponent all 1's
|
||||||
assign XExpMaxE = FmtE ? &X[`FLEN-2:`NF] : &XLen1[`LEN1-2:`NF1];
|
assign XExpMaxE = FmtE ? &X[`FLEN-2:`NF] : &XLen1[`LEN1-2:`NF1];
|
||||||
assign YExpMaxE = FmtE ? &Y[`FLEN-2:`NF] : &YLen1[`LEN1-2:`NF1];
|
assign YExpMaxE = FmtE ? &Y[`FLEN-2:`NF] : &YLen1[`LEN1-2:`NF1];
|
||||||
assign ZExpMaxE = FmtE ? &Z[`FLEN-2:`NF] : &ZLen1[`LEN1-2:`NF1];
|
assign ZExpMaxE = FmtE ? &Z[`FLEN-2:`NF] : &ZLen1[`LEN1-2:`NF1];
|
||||||
|
|
||||||
|
|
||||||
end else if (`FPSIZES == 3) begin
|
end else if (`FPSIZES == 3) begin // three floating point precsions supported
|
||||||
logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Bottom half or NaN, if not properly NaN boxed
|
|
||||||
logic [`LEN2-1:0] XLen2, YLen2, ZLen2; // Bottom half or NaN, if not properly NaN boxed
|
//***need better names for these constants
|
||||||
|
// largest format | larger format | smallest format
|
||||||
|
//---------------------------------------------------
|
||||||
|
// `FLEN | `LEN1 | `LEN2 length of floating point number
|
||||||
|
// `NE | `NE1 | `NE2 length of exponent
|
||||||
|
// `NF | `NF1 | `NF2 length of fraction
|
||||||
|
// `BIAS | `BIAS1 | `BIAS2 exponent's bias value
|
||||||
|
// `FMT | `FMT1 | `FMT2 precision's format value - Q=11 D=01 S=00 H=10
|
||||||
|
|
||||||
|
// Possible combinantions specified by spec:
|
||||||
|
// quad and double and single
|
||||||
|
// double and single and half
|
||||||
|
|
||||||
|
// Not needed but can also handle:
|
||||||
|
// quad and double and half
|
||||||
|
// quad and single and half
|
||||||
|
|
||||||
|
logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Remove NaN boxing or NaN, if not properly NaN boxed for larger percision
|
||||||
|
logic [`LEN2-1:0] XLen2, YLen2, ZLen2; // Remove NaN boxing or NaN, if not properly NaN boxed for smallest precision
|
||||||
|
|
||||||
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN
|
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for larger precision
|
||||||
assign XLen1 = &X[`FLEN-1:`LEN1] ? X[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
assign XLen1 = &X[`FLEN-1:`LEN1] ? X[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
||||||
assign YLen1 = &Y[`FLEN-1:`LEN1] ? Y[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
assign YLen1 = &Y[`FLEN-1:`LEN1] ? Y[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
||||||
assign ZLen1 = &Z[`FLEN-1:`LEN1] ? Z[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
assign ZLen1 = &Z[`FLEN-1:`LEN1] ? Z[`LEN1-1:0] : {1'b0, {`NE1+1{1'b1}}, (`NF1-1)'(0)};
|
||||||
|
|
||||||
|
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for smaller precision
|
||||||
assign XLen2 = &X[`FLEN-1:`LEN2] ? X[`LEN2-1:0] : {1'b0, {`NE2+1{1'b1}}, (`NF2-1)'(0)};
|
assign XLen2 = &X[`FLEN-1:`LEN2] ? X[`LEN2-1:0] : {1'b0, {`NE2+1{1'b1}}, (`NF2-1)'(0)};
|
||||||
assign YLen2 = &Y[`FLEN-1:`LEN2] ? Y[`LEN2-1:0] : {1'b0, {`NE2+1{1'b1}}, (`NF2-1)'(0)};
|
assign YLen2 = &Y[`FLEN-1:`LEN2] ? Y[`LEN2-1:0] : {1'b0, {`NE2+1{1'b1}}, (`NF2-1)'(0)};
|
||||||
assign ZLen2 = &Z[`FLEN-1:`LEN2] ? Z[`LEN2-1:0] : {1'b0, {`NE2+1{1'b1}}, (`NF2-1)'(0)};
|
assign ZLen2 = &Z[`FLEN-1:`LEN2] ? Z[`LEN2-1:0] : {1'b0, {`NE2+1{1'b1}}, (`NF2-1)'(0)};
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
case (FmtE)
|
case (FmtE)
|
||||||
`FMT: begin
|
`FMT: begin // if input is largest precision (`FLEN - ie quad or double)
|
||||||
assign XSgnE = X[`FLEN-1];
|
// extract the sign bit
|
||||||
assign YSgnE = Y[`FLEN-1];
|
XSgnE = X[`FLEN-1];
|
||||||
assign ZSgnE = Z[`FLEN-1];
|
YSgnE = Y[`FLEN-1];
|
||||||
|
ZSgnE = Z[`FLEN-1];
|
||||||
|
|
||||||
assign XExpE = X[`FLEN-2:`NF];
|
// extract the exponent
|
||||||
assign YExpE = Y[`FLEN-2:`NF];
|
XExpE = X[`FLEN-2:`NF];
|
||||||
assign ZExpE = Z[`FLEN-2:`NF];
|
YExpE = Y[`FLEN-2:`NF];
|
||||||
|
ZExpE = Z[`FLEN-2:`NF];
|
||||||
|
|
||||||
assign XFracE = X[`NF-1:0];
|
// extract the fraction
|
||||||
assign YFracE = Y[`NF-1:0];
|
XFracE = X[`NF-1:0];
|
||||||
assign ZFracE = Z[`NF-1:0];
|
YFracE = Y[`NF-1:0];
|
||||||
|
ZFracE = Z[`NF-1:0];
|
||||||
|
|
||||||
assign XExpNonzero = |X[`FLEN-2:`NF];
|
// is the exponent non-zero
|
||||||
assign YExpNonzero = |Y[`FLEN-2:`NF];
|
XExpNonzero = |X[`FLEN-2:`NF];
|
||||||
assign ZExpNonzero = |Z[`FLEN-2:`NF];
|
YExpNonzero = |Y[`FLEN-2:`NF];
|
||||||
|
ZExpNonzero = |Z[`FLEN-2:`NF];
|
||||||
|
|
||||||
assign XExpMaxE = &X[`FLEN-2:`NF];
|
// is the exponent all 1's
|
||||||
assign YExpMaxE = &Y[`FLEN-2:`NF];
|
XExpMaxE = &X[`FLEN-2:`NF];
|
||||||
assign ZExpMaxE = &Z[`FLEN-2:`NF];
|
YExpMaxE = &Y[`FLEN-2:`NF];
|
||||||
|
ZExpMaxE = &Z[`FLEN-2:`NF];
|
||||||
end
|
end
|
||||||
`FMT1: begin
|
`FMT1: begin // if input is larger precsion (`LEN1 - double or single)
|
||||||
assign XSgnE = XLen1[`LEN1-1];
|
|
||||||
assign YSgnE = YLen1[`LEN1-1];
|
// extract the sign bit
|
||||||
assign ZSgnE = ZLen1[`LEN1-1];
|
XSgnE = XLen1[`LEN1-1];
|
||||||
|
YSgnE = YLen1[`LEN1-1];
|
||||||
|
ZSgnE = ZLen1[`LEN1-1];
|
||||||
|
|
||||||
// example double to single conversion:
|
// example double to single conversion:
|
||||||
// 1023 = 0011 1111 1111
|
// 1023 = 0011 1111 1111
|
||||||
@ -129,26 +185,33 @@ module unpack (
|
|||||||
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
||||||
// dexp = 0bdd dbbb bbbb
|
// dexp = 0bdd dbbb bbbb
|
||||||
// also need to take into account possible zero/denorm/inf/NaN values
|
// also need to take into account possible zero/denorm/inf/NaN values
|
||||||
assign XExpE = {XLen1[`LEN1-2], {`NE-`NE1{~XLen1[`LEN1-2]&~XExpZero|XExpMaxE}}, XLen1[`LEN1-3:`NF1]};
|
|
||||||
assign YExpE = {YLen1[`LEN1-2], {`NE-`NE1{~YLen1[`LEN1-2]&~YExpZero|YExpMaxE}}, YLen1[`LEN1-3:`NF1]};
|
|
||||||
assign ZExpE = {ZLen1[`LEN1-2], {`NE-`NE1{~ZLen1[`LEN1-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`LEN1-3:`NF1]};
|
|
||||||
|
|
||||||
assign XFracE = {XLen1[`NF1-1:0], (`NF-`NF1)'(0)};
|
// convert the larger precision's exponent to use the largest precision's bias
|
||||||
assign YFracE = {YLen1[`NF1-1:0], (`NF-`NF1)'(0)};
|
XExpE = {XLen1[`LEN1-2], {`NE-`NE1{~XLen1[`LEN1-2]&~XExpZero|XExpMaxE}}, XLen1[`LEN1-3:`NF1]};
|
||||||
assign ZFracE = {ZLen1[`NF1-1:0], (`NF-`NF1)'(0)};
|
YExpE = {YLen1[`LEN1-2], {`NE-`NE1{~YLen1[`LEN1-2]&~YExpZero|YExpMaxE}}, YLen1[`LEN1-3:`NF1]};
|
||||||
|
ZExpE = {ZLen1[`LEN1-2], {`NE-`NE1{~ZLen1[`LEN1-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`LEN1-3:`NF1]};
|
||||||
|
|
||||||
assign XExpNonzero = |XLen1[`LEN1-2:`NF1];
|
// extract the fraction and add the nessesary trailing zeros
|
||||||
assign YExpNonzero = |YLen1[`LEN1-2:`NF1];
|
XFracE = {XLen1[`NF1-1:0], (`NF-`NF1)'(0)};
|
||||||
assign ZExpNonzero = |ZLen1[`LEN1-2:`NF1];
|
YFracE = {YLen1[`NF1-1:0], (`NF-`NF1)'(0)};
|
||||||
|
ZFracE = {ZLen1[`NF1-1:0], (`NF-`NF1)'(0)};
|
||||||
|
|
||||||
assign XExpMaxE = &XLen1[`LEN1-2:`NF1];
|
// is the exponent non-zero
|
||||||
assign YExpMaxE = &YLen1[`LEN1-2:`NF1];
|
XExpNonzero = |XLen1[`LEN1-2:`NF1];
|
||||||
assign ZExpMaxE = &ZLen1[`LEN1-2:`NF1];
|
YExpNonzero = |YLen1[`LEN1-2:`NF1];
|
||||||
|
ZExpNonzero = |ZLen1[`LEN1-2:`NF1];
|
||||||
|
|
||||||
|
// is the exponent all 1's
|
||||||
|
XExpMaxE = &XLen1[`LEN1-2:`NF1];
|
||||||
|
YExpMaxE = &YLen1[`LEN1-2:`NF1];
|
||||||
|
ZExpMaxE = &ZLen1[`LEN1-2:`NF1];
|
||||||
end
|
end
|
||||||
`FMT2: begin
|
`FMT2: begin // if input is smallest precsion (`LEN2 - single or half)
|
||||||
assign XSgnE = XLen2[`LEN2-1];
|
|
||||||
assign YSgnE = YLen2[`LEN2-1];
|
// exctract the sign bit
|
||||||
assign ZSgnE = ZLen2[`LEN2-1];
|
XSgnE = XLen2[`LEN2-1];
|
||||||
|
YSgnE = YLen2[`LEN2-1];
|
||||||
|
ZSgnE = ZLen2[`LEN2-1];
|
||||||
|
|
||||||
// example double to single conversion:
|
// example double to single conversion:
|
||||||
// 1023 = 0011 1111 1111
|
// 1023 = 0011 1111 1111
|
||||||
@ -157,87 +220,110 @@ module unpack (
|
|||||||
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
||||||
// dexp = 0bdd dbbb bbbb
|
// dexp = 0bdd dbbb bbbb
|
||||||
// also need to take into account possible zero/denorm/inf/NaN values
|
// also need to take into account possible zero/denorm/inf/NaN values
|
||||||
assign XExpE = {XLen2[`LEN2-2], {`NE-`NE2{~XLen2[`LEN2-2]&~XExpZero|XExpMaxE}}, XLen2[`LEN2-3:`NF2]};
|
|
||||||
assign YExpE = {YLen2[`LEN2-2], {`NE-`NE2{~YLen2[`LEN2-2]&~YExpZero|YExpMaxE}}, YLen2[`LEN2-3:`NF2]};
|
// convert the smallest precision's exponent to use the largest precision's bias
|
||||||
assign ZExpE = {ZLen2[`LEN2-2], {`NE-`NE2{~ZLen2[`LEN2-2]&~ZExpZero|ZExpMaxE}}, ZLen2[`LEN2-3:`NF2]};
|
XExpE = {XLen2[`LEN2-2], {`NE-`NE2{~XLen2[`LEN2-2]&~XExpZero|XExpMaxE}}, XLen2[`LEN2-3:`NF2]};
|
||||||
|
YExpE = {YLen2[`LEN2-2], {`NE-`NE2{~YLen2[`LEN2-2]&~YExpZero|YExpMaxE}}, YLen2[`LEN2-3:`NF2]};
|
||||||
|
ZExpE = {ZLen2[`LEN2-2], {`NE-`NE2{~ZLen2[`LEN2-2]&~ZExpZero|ZExpMaxE}}, ZLen2[`LEN2-3:`NF2]};
|
||||||
|
|
||||||
assign XFracE = {XLen2[`NF2-1:0], (`NF-`NF2)'(0)};
|
// extract the fraction and add the nessesary trailing zeros
|
||||||
assign YFracE = {YLen2[`NF2-1:0], (`NF-`NF2)'(0)};
|
XFracE = {XLen2[`NF2-1:0], (`NF-`NF2)'(0)};
|
||||||
assign ZFracE = {ZLen2[`NF2-1:0], (`NF-`NF2)'(0)};
|
YFracE = {YLen2[`NF2-1:0], (`NF-`NF2)'(0)};
|
||||||
|
ZFracE = {ZLen2[`NF2-1:0], (`NF-`NF2)'(0)};
|
||||||
|
|
||||||
assign XExpNonzero = |XLen2[`LEN2-2:`NF2];
|
// is the exponent non-zero
|
||||||
assign YExpNonzero = |YLen2[`LEN2-2:`NF2];
|
XExpNonzero = |XLen2[`LEN2-2:`NF2];
|
||||||
assign ZExpNonzero = |ZLen2[`LEN2-2:`NF2];
|
YExpNonzero = |YLen2[`LEN2-2:`NF2];
|
||||||
|
ZExpNonzero = |ZLen2[`LEN2-2:`NF2];
|
||||||
|
|
||||||
assign XExpMaxE = &XLen2[`LEN2-2:`NF2];
|
// is the exponent all 1's
|
||||||
assign YExpMaxE = &YLen2[`LEN2-2:`NF2];
|
XExpMaxE = &XLen2[`LEN2-2:`NF2];
|
||||||
assign ZExpMaxE = &ZLen2[`LEN2-2:`NF2];
|
YExpMaxE = &YLen2[`LEN2-2:`NF2];
|
||||||
|
ZExpMaxE = &ZLen2[`LEN2-2:`NF2];
|
||||||
end
|
end
|
||||||
default: begin
|
default: begin
|
||||||
assign XSgnE = 0;
|
XSgnE = 0;
|
||||||
assign YSgnE = 0;
|
YSgnE = 0;
|
||||||
assign ZSgnE = 0;
|
ZSgnE = 0;
|
||||||
assign XExpE = 0;
|
XExpE = 0;
|
||||||
assign YExpE = 0;
|
YExpE = 0;
|
||||||
assign ZExpE = 0;
|
ZExpE = 0;
|
||||||
assign XFracE = 0;
|
XFracE = 0;
|
||||||
assign YFracE = 0;
|
YFracE = 0;
|
||||||
assign ZFracE = 0;
|
ZFracE = 0;
|
||||||
assign XExpNonzero = 0;
|
XExpNonzero = 0;
|
||||||
assign YExpNonzero = 0;
|
YExpNonzero = 0;
|
||||||
assign ZExpNonzero = 0;
|
ZExpNonzero = 0;
|
||||||
assign XExpMaxE = 0;
|
XExpMaxE = 0;
|
||||||
assign YExpMaxE = 0;
|
YExpMaxE = 0;
|
||||||
assign ZExpMaxE = 0;
|
ZExpMaxE = 0;
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
end else begin
|
end else begin // if all precsisons are supported - quad, double, single, and half
|
||||||
logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Bottom half or NaN, if not properly NaN boxed
|
|
||||||
logic [`LEN2-1:0] XLen2, YLen2, ZLen2; // Bottom half or NaN, if not properly NaN boxed
|
// quad | double | single | half
|
||||||
logic [`LEN2-1:0] XLen3, YLen3, ZLen3; // Bottom half or NaN, if not properly NaN boxed
|
//-------------------------------------------------------------------
|
||||||
|
// `Q_LEN | `D_LEN | `S_LEN | `H_LEN length of floating point number
|
||||||
|
// `Q_NE | `D_NE | `S_NE | `H_NE length of exponent
|
||||||
|
// `Q_NF | `D_NF | `S_NF | `H_NF length of fraction
|
||||||
|
// `Q_BIAS | `D_BIAS | `S_BIAS | `H_BIAS exponent's bias value
|
||||||
|
// `Q_FMT | `D_FMT | `S_FMT | `H_FMT precision's format value - Q=11 D=01 S=00 H=10
|
||||||
|
|
||||||
|
|
||||||
|
logic [`LEN1-1:0] XLen1, YLen1, ZLen1; // Remove NaN boxing or NaN, if not properly NaN boxed for double percision
|
||||||
|
logic [`LEN2-1:0] XLen2, YLen2, ZLen2; // Remove NaN boxing or NaN, if not properly NaN boxed for single percision
|
||||||
|
logic [`LEN2-1:0] XLen3, YLen3, ZLen3; // Remove NaN boxing or NaN, if not properly NaN boxed for half percision
|
||||||
|
|
||||||
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN
|
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for double precision
|
||||||
assign XLen1 = &X[`FLEN-1:`D_LEN] ? X[`D_LEN-1:0] : {1'b0, {`D_NE+1{1'b1}}, (`D_NF-1)'(0)};
|
assign XLen1 = &X[`Q_LEN-1:`D_LEN] ? X[`D_LEN-1:0] : {1'b0, {`D_NE+1{1'b1}}, (`D_NF-1)'(0)};
|
||||||
assign YLen1 = &Y[`FLEN-1:`D_LEN] ? Y[`D_LEN-1:0] : {1'b0, {`D_NE+1{1'b1}}, (`D_NF-1)'(0)};
|
assign YLen1 = &Y[`Q_LEN-1:`D_LEN] ? Y[`D_LEN-1:0] : {1'b0, {`D_NE+1{1'b1}}, (`D_NF-1)'(0)};
|
||||||
assign ZLen1 = &Z[`FLEN-1:`D_LEN] ? Z[`D_LEN-1:0] : {1'b0, {`D_NE+1{1'b1}}, (`D_NF-1)'(0)};
|
assign ZLen1 = &Z[`Q_LEN-1:`D_LEN] ? Z[`D_LEN-1:0] : {1'b0, {`D_NE+1{1'b1}}, (`D_NF-1)'(0)};
|
||||||
|
|
||||||
assign XLen2 = &X[`FLEN-1:`S_LEN] ? X[`S_LEN-1:0] : {1'b0, {`S_NE+1{1'b1}}, (`S_NF-1)'(0)};
|
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for single precision
|
||||||
assign YLen2 = &Y[`FLEN-1:`S_LEN] ? Y[`S_LEN-1:0] : {1'b0, {`S_NE+1{1'b1}}, (`S_NF-1)'(0)};
|
assign XLen2 = &X[`Q_LEN-1:`S_LEN] ? X[`S_LEN-1:0] : {1'b0, {`S_NE+1{1'b1}}, (`S_NF-1)'(0)};
|
||||||
assign ZLen2 = &Z[`FLEN-1:`S_LEN] ? Z[`S_LEN-1:0] : {1'b0, {`S_NE+1{1'b1}}, (`S_NF-1)'(0)};
|
assign YLen2 = &Y[`Q_LEN-1:`S_LEN] ? Y[`S_LEN-1:0] : {1'b0, {`S_NE+1{1'b1}}, (`S_NF-1)'(0)};
|
||||||
|
assign ZLen2 = &Z[`Q_LEN-1:`S_LEN] ? Z[`S_LEN-1:0] : {1'b0, {`S_NE+1{1'b1}}, (`S_NF-1)'(0)};
|
||||||
|
|
||||||
assign XLen3 = &X[`FLEN-1:`H_LEN] ? X[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)};
|
// Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for half precision
|
||||||
assign YLen3 = &Y[`FLEN-1:`H_LEN] ? Y[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)};
|
assign XLen3 = &X[`Q_LEN-1:`H_LEN] ? X[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)};
|
||||||
assign ZLen3 = &Z[`FLEN-1:`H_LEN] ? Z[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)};
|
assign YLen3 = &Y[`Q_LEN-1:`H_LEN] ? Y[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)};
|
||||||
|
assign ZLen3 = &Z[`Q_LEN-1:`H_LEN] ? Z[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)};
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
case (FmtE)
|
case (FmtE)
|
||||||
2'b11: begin
|
`Q_BIAS: begin // if input is quad percision
|
||||||
assign XSgnE = X[`FLEN-1];
|
// extract sign bit
|
||||||
assign YSgnE = Y[`FLEN-1];
|
XSgnE = X[`Q_LEN-1];
|
||||||
assign ZSgnE = Z[`FLEN-1];
|
YSgnE = Y[`Q_LEN-1];
|
||||||
|
ZSgnE = Z[`Q_LEN-1];
|
||||||
|
|
||||||
assign XExpE = X[`FLEN-2:`NF];
|
// extract the exponent
|
||||||
assign YExpE = Y[`FLEN-2:`NF];
|
XExpE = X[`Q_LEN-2:`Q_NF];
|
||||||
assign ZExpE = Z[`FLEN-2:`NF];
|
YExpE = Y[`Q_LEN-2:`Q_NF];
|
||||||
|
ZExpE = Z[`Q_LEN-2:`Q_NF];
|
||||||
|
|
||||||
assign XFracE = X[`NF-1:0];
|
// extract the fraction
|
||||||
assign YFracE = Y[`NF-1:0];
|
XFracE = X[`Q_NF-1:0];
|
||||||
assign ZFracE = Z[`NF-1:0];
|
YFracE = Y[`Q_NF-1:0];
|
||||||
|
ZFracE = Z[`Q_NF-1:0];
|
||||||
|
|
||||||
assign XExpNonzero = |X[`FLEN-2:`NF];
|
// is the exponent non-zero
|
||||||
assign YExpNonzero = |Y[`FLEN-2:`NF];
|
XExpNonzero = |X[`Q_LEN-2:`Q_NF];
|
||||||
assign ZExpNonzero = |Z[`FLEN-2:`NF];
|
YExpNonzero = |Y[`Q_LEN-2:`Q_NF];
|
||||||
|
ZExpNonzero = |Z[`Q_LEN-2:`Q_NF];
|
||||||
|
|
||||||
assign XExpMaxE = &X[`FLEN-2:`NF];
|
// is the exponent all 1's
|
||||||
assign YExpMaxE = &Y[`FLEN-2:`NF];
|
XExpMaxE = &X[`Q_LEN-2:`Q_NF];
|
||||||
assign ZExpMaxE = &Z[`FLEN-2:`NF];
|
YExpMaxE = &Y[`Q_LEN-2:`Q_NF];
|
||||||
|
ZExpMaxE = &Z[`Q_LEN-2:`Q_NF];
|
||||||
end
|
end
|
||||||
2'b01: begin
|
`D_BIAS: begin // if input is double percision
|
||||||
assign XSgnE = XLen1[`LEN1-1];
|
// extract sign bit
|
||||||
assign YSgnE = YLen1[`LEN1-1];
|
XSgnE = XLen1[`D_LEN-1];
|
||||||
assign ZSgnE = ZLen1[`LEN1-1];
|
YSgnE = YLen1[`D_LEN-1];
|
||||||
|
ZSgnE = ZLen1[`D_LEN-1];
|
||||||
|
|
||||||
// example double to single conversion:
|
// example double to single conversion:
|
||||||
// 1023 = 0011 1111 1111
|
// 1023 = 0011 1111 1111
|
||||||
@ -246,26 +332,32 @@ module unpack (
|
|||||||
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
||||||
// dexp = 0bdd dbbb bbbb
|
// dexp = 0bdd dbbb bbbb
|
||||||
// also need to take into account possible zero/denorm/inf/NaN values
|
// also need to take into account possible zero/denorm/inf/NaN values
|
||||||
assign XExpE = {XLen1[`D_LEN-2], {`NE-`D_NE{~XLen1[`D_LEN-2]&~XExpZero|XExpMaxE}}, XLen1[`D_LEN-3:`D_NF]};
|
|
||||||
assign YExpE = {YLen1[`D_LEN-2], {`NE-`D_NE{~YLen1[`D_LEN-2]&~YExpZero|YExpMaxE}}, YLen1[`D_LEN-3:`D_NF]};
|
// convert the double precsion exponent into quad precsion
|
||||||
assign ZExpE = {ZLen1[`D_LEN-2], {`NE-`D_NE{~ZLen1[`D_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`D_LEN-3:`D_NF]};
|
XExpE = {XLen1[`D_LEN-2], {`Q_NE-`D_NE{~XLen1[`D_LEN-2]&~XExpZero|XExpMaxE}}, XLen1[`D_LEN-3:`D_NF]};
|
||||||
|
YExpE = {YLen1[`D_LEN-2], {`Q_NE-`D_NE{~YLen1[`D_LEN-2]&~YExpZero|YExpMaxE}}, YLen1[`D_LEN-3:`D_NF]};
|
||||||
|
ZExpE = {ZLen1[`D_LEN-2], {`Q_NE-`D_NE{~ZLen1[`D_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`D_LEN-3:`D_NF]};
|
||||||
|
|
||||||
assign XFracE = {XLen1[`D_NE-1:0], (`NF-`D_NE)'(0)};
|
// extract the fraction and add the nessesary trailing zeros
|
||||||
assign YFracE = {YLen1[`D_NE-1:0], (`NF-`D_NE)'(0)};
|
XFracE = {XLen1[`D_NE-1:0], (`Q_NF-`D_NE)'(0)};
|
||||||
assign ZFracE = {ZLen1[`D_NE-1:0], (`NF-`D_NE)'(0)};
|
YFracE = {YLen1[`D_NE-1:0], (`Q_NF-`D_NE)'(0)};
|
||||||
|
ZFracE = {ZLen1[`D_NE-1:0], (`Q_NF-`D_NE)'(0)};
|
||||||
|
|
||||||
assign XExpNonzero = |XLen1[`D_LEN-2:`D_NE];
|
// is the exponent non-zero
|
||||||
assign YExpNonzero = |YLen1[`D_LEN-2:`D_NE];
|
XExpNonzero = |XLen1[`D_LEN-2:`D_NE];
|
||||||
assign ZExpNonzero = |ZLen1[`D_LEN-2:`D_NE];
|
YExpNonzero = |YLen1[`D_LEN-2:`D_NE];
|
||||||
|
ZExpNonzero = |ZLen1[`D_LEN-2:`D_NE];
|
||||||
|
|
||||||
assign XExpMaxE = &XLen1[`D_LEN-2:`D_NE];
|
// is the exponent all 1's
|
||||||
assign YExpMaxE = &YLen1[`D_LEN-2:`D_NE];
|
XExpMaxE = &XLen1[`D_LEN-2:`D_NE];
|
||||||
assign ZExpMaxE = &ZLen1[`D_LEN-2:`D_NE];
|
YExpMaxE = &YLen1[`D_LEN-2:`D_NE];
|
||||||
|
ZExpMaxE = &ZLen1[`D_LEN-2:`D_NE];
|
||||||
end
|
end
|
||||||
2'b00: begin
|
`S_BIAS: begin // if input is single percision
|
||||||
assign XSgnE = XLen2[`S_LEN-1];
|
// extract sign bit
|
||||||
assign YSgnE = YLen2[`S_LEN-1];
|
XSgnE = XLen2[`S_LEN-1];
|
||||||
assign ZSgnE = ZLen2[`S_LEN-1];
|
YSgnE = YLen2[`S_LEN-1];
|
||||||
|
ZSgnE = ZLen2[`S_LEN-1];
|
||||||
|
|
||||||
// example double to single conversion:
|
// example double to single conversion:
|
||||||
// 1023 = 0011 1111 1111
|
// 1023 = 0011 1111 1111
|
||||||
@ -274,26 +366,32 @@ module unpack (
|
|||||||
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
||||||
// dexp = 0bdd dbbb bbbb
|
// dexp = 0bdd dbbb bbbb
|
||||||
// also need to take into account possible zero/denorm/inf/NaN values
|
// also need to take into account possible zero/denorm/inf/NaN values
|
||||||
assign XExpE = {XLen2[`S_LEN-2], {`NE-`S_NE{~XLen2[`S_LEN-2]&~XExpZero|XExpMaxE}}, XLen2[`S_LEN-3:`S_NF]};
|
|
||||||
assign YExpE = {YLen2[`S_LEN-2], {`NE-`S_NE{~YLen2[`S_LEN-2]&~YExpZero|YExpMaxE}}, YLen2[`S_LEN-3:`S_NF]};
|
// convert the single precsion exponent into quad precsion
|
||||||
assign ZExpE = {ZLen2[`S_LEN-2], {`NE-`S_NE{~ZLen2[`S_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen2[`S_LEN-3:`S_NF]};
|
XExpE = {XLen2[`S_LEN-2], {`Q_NE-`S_NE{~XLen2[`S_LEN-2]&~XExpZero|XExpMaxE}}, XLen2[`S_LEN-3:`S_NF]};
|
||||||
|
YExpE = {YLen2[`S_LEN-2], {`Q_NE-`S_NE{~YLen2[`S_LEN-2]&~YExpZero|YExpMaxE}}, YLen2[`S_LEN-3:`S_NF]};
|
||||||
|
ZExpE = {ZLen2[`S_LEN-2], {`Q_NE-`S_NE{~ZLen2[`S_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen2[`S_LEN-3:`S_NF]};
|
||||||
|
|
||||||
assign XFracE = {XLen2[`S_NF-1:0], (`NF-`S_NF)'(0)};
|
// extract the fraction and add the nessesary trailing zeros
|
||||||
assign YFracE = {YLen2[`S_NF-1:0], (`NF-`S_NF)'(0)};
|
XFracE = {XLen2[`S_NF-1:0], (`Q_NF-`S_NF)'(0)};
|
||||||
assign ZFracE = {ZLen2[`S_NF-1:0], (`NF-`S_NF)'(0)};
|
YFracE = {YLen2[`S_NF-1:0], (`Q_NF-`S_NF)'(0)};
|
||||||
|
ZFracE = {ZLen2[`S_NF-1:0], (`Q_NF-`S_NF)'(0)};
|
||||||
|
|
||||||
assign XExpNonzero = |XLen2[`S_LEN-2:`S_NF];
|
// is the exponent non-zero
|
||||||
assign YExpNonzero = |YLen2[`S_LEN-2:`S_NF];
|
XExpNonzero = |XLen2[`S_LEN-2:`S_NF];
|
||||||
assign ZExpNonzero = |ZLen2[`S_LEN-2:`S_NF];
|
YExpNonzero = |YLen2[`S_LEN-2:`S_NF];
|
||||||
|
ZExpNonzero = |ZLen2[`S_LEN-2:`S_NF];
|
||||||
|
|
||||||
assign XExpMaxE = &XLen2[`S_LEN-2:`S_NF];
|
// is the exponent all 1's
|
||||||
assign YExpMaxE = &YLen2[`S_LEN-2:`S_NF];
|
XExpMaxE = &XLen2[`S_LEN-2:`S_NF];
|
||||||
assign ZExpMaxE = &ZLen2[`S_LEN-2:`S_NF];
|
YExpMaxE = &YLen2[`S_LEN-2:`S_NF];
|
||||||
|
ZExpMaxE = &ZLen2[`S_LEN-2:`S_NF];
|
||||||
end
|
end
|
||||||
2'b10: begin
|
`H_BIAS: begin // if input is half percision
|
||||||
assign XSgnE = XLen3[`H_LEN-1];
|
// extract sign bit
|
||||||
assign YSgnE = YLen3[`H_LEN-1];
|
XSgnE = XLen3[`H_LEN-1];
|
||||||
assign ZSgnE = ZLen3[`H_LEN-1];
|
YSgnE = YLen3[`H_LEN-1];
|
||||||
|
ZSgnE = ZLen3[`H_LEN-1];
|
||||||
|
|
||||||
// example double to single conversion:
|
// example double to single conversion:
|
||||||
// 1023 = 0011 1111 1111
|
// 1023 = 0011 1111 1111
|
||||||
@ -302,58 +400,72 @@ module unpack (
|
|||||||
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
// sexp = 0000 bbbb bbbb (add this) b = bit d = ~b
|
||||||
// dexp = 0bdd dbbb bbbb
|
// dexp = 0bdd dbbb bbbb
|
||||||
// also need to take into account possible zero/denorm/inf/NaN values
|
// also need to take into account possible zero/denorm/inf/NaN values
|
||||||
assign XExpE = {XLen3[`H_LEN-2], {`NE-`H_NE{~XLen3[`H_LEN-2]&~XExpZero|XExpMaxE}}, XLen3[`H_LEN-3:`H_NF]};
|
|
||||||
assign YExpE = {YLen3[`H_LEN-2], {`NE-`H_NE{~YLen3[`H_LEN-2]&~YExpZero|YExpMaxE}}, YLen3[`H_LEN-3:`H_NF]};
|
// convert the half precsion exponent into quad precsion
|
||||||
assign ZExpE = {ZLen3[`H_LEN-2], {`NE-`H_NE{~ZLen3[`H_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen3[`H_LEN-3:`H_NF]};
|
XExpE = {XLen3[`H_LEN-2], {`Q_NE-`H_NE{~XLen3[`H_LEN-2]&~XExpZero|XExpMaxE}}, XLen3[`H_LEN-3:`H_NF]};
|
||||||
|
YExpE = {YLen3[`H_LEN-2], {`Q_NE-`H_NE{~YLen3[`H_LEN-2]&~YExpZero|YExpMaxE}}, YLen3[`H_LEN-3:`H_NF]};
|
||||||
|
ZExpE = {ZLen3[`H_LEN-2], {`Q_NE-`H_NE{~ZLen3[`H_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen3[`H_LEN-3:`H_NF]};
|
||||||
|
|
||||||
assign XFracE = {XLen3[`H_NF-1:0], (`NF-`H_NF)'(0)};
|
// extract the fraction and add the nessesary trailing zeros
|
||||||
assign YFracE = {YLen3[`H_NF-1:0], (`NF-`H_NF)'(0)};
|
XFracE = {XLen3[`H_NF-1:0], (`Q_NF-`H_NF)'(0)};
|
||||||
assign ZFracE = {ZLen3[`H_NF-1:0], (`NF-`H_NF)'(0)};
|
YFracE = {YLen3[`H_NF-1:0], (`Q_NF-`H_NF)'(0)};
|
||||||
|
ZFracE = {ZLen3[`H_NF-1:0], (`Q_NF-`H_NF)'(0)};
|
||||||
|
|
||||||
assign XExpNonzero = |XLen3[`H_LEN-2:`H_NF];
|
// is the exponent non-zero
|
||||||
assign YExpNonzero = |YLen3[`H_LEN-2:`H_NF];
|
XExpNonzero = |XLen3[`H_LEN-2:`H_NF];
|
||||||
assign ZExpNonzero = |ZLen3[`H_LEN-2:`H_NF];
|
YExpNonzero = |YLen3[`H_LEN-2:`H_NF];
|
||||||
|
ZExpNonzero = |ZLen3[`H_LEN-2:`H_NF];
|
||||||
|
|
||||||
assign XExpMaxE = &XLen3[`H_LEN-2:`H_NF];
|
// is the exponent all 1's
|
||||||
assign YExpMaxE = &YLen3[`H_LEN-2:`H_NF];
|
XExpMaxE = &XLen3[`H_LEN-2:`H_NF];
|
||||||
assign ZExpMaxE = &ZLen3[`H_LEN-2:`H_NF];
|
YExpMaxE = &YLen3[`H_LEN-2:`H_NF];
|
||||||
|
ZExpMaxE = &ZLen3[`H_LEN-2:`H_NF];
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// is the exponent all 0's
|
||||||
assign XExpZero = ~XExpNonzero;
|
assign XExpZero = ~XExpNonzero;
|
||||||
assign YExpZero = ~YExpNonzero;
|
assign YExpZero = ~YExpNonzero;
|
||||||
assign ZExpZero = ~ZExpNonzero;
|
assign ZExpZero = ~ZExpNonzero;
|
||||||
|
|
||||||
|
// is the fraction zero
|
||||||
assign XFracZero = ~|XFracE;
|
assign XFracZero = ~|XFracE;
|
||||||
assign YFracZero = ~|YFracE;
|
assign YFracZero = ~|YFracE;
|
||||||
assign ZFracZero = ~|ZFracE;
|
assign ZFracZero = ~|ZFracE;
|
||||||
|
|
||||||
|
// add the assumed one (or zero if denormal or zero) to create the mantissa
|
||||||
assign XManE = {XExpNonzero, XFracE};
|
assign XManE = {XExpNonzero, XFracE};
|
||||||
assign YManE = {YExpNonzero, YFracE};
|
assign YManE = {YExpNonzero, YFracE};
|
||||||
assign ZManE = {ZExpNonzero, ZFracE};
|
assign ZManE = {ZExpNonzero, ZFracE};
|
||||||
|
|
||||||
|
// is X normalized
|
||||||
assign XNormE = ~(XExpMaxE|XExpZero);
|
assign XNormE = ~(XExpMaxE|XExpZero);
|
||||||
|
|
||||||
// force single precision input to be a NaN if it isn't properly Nan Boxed
|
// is the input a NaN
|
||||||
|
// - force to be a NaN if it isn't properly Nan Boxed
|
||||||
assign XNaNE = XExpMaxE & ~XFracZero;
|
assign XNaNE = XExpMaxE & ~XFracZero;
|
||||||
assign YNaNE = YExpMaxE & ~YFracZero;
|
assign YNaNE = YExpMaxE & ~YFracZero;
|
||||||
assign ZNaNE = ZExpMaxE & ~ZFracZero;
|
assign ZNaNE = ZExpMaxE & ~ZFracZero;
|
||||||
|
|
||||||
|
// is the input a singnaling NaN
|
||||||
assign XSNaNE = XNaNE&~XFracE[`NF-1];
|
assign XSNaNE = XNaNE&~XFracE[`NF-1];
|
||||||
assign YSNaNE = YNaNE&~YFracE[`NF-1];
|
assign YSNaNE = YNaNE&~YFracE[`NF-1];
|
||||||
assign ZSNaNE = ZNaNE&~ZFracE[`NF-1];
|
assign ZSNaNE = ZNaNE&~ZFracE[`NF-1];
|
||||||
|
|
||||||
|
// is the input denormalized
|
||||||
assign XDenormE = XExpZero & ~XFracZero;
|
assign XDenormE = XExpZero & ~XFracZero;
|
||||||
assign YDenormE = YExpZero & ~YFracZero;
|
assign YDenormE = YExpZero & ~YFracZero;
|
||||||
assign ZDenormE = ZExpZero & ~ZFracZero;
|
assign ZDenormE = ZExpZero & ~ZFracZero;
|
||||||
|
|
||||||
|
// is the input infinity
|
||||||
assign XInfE = XExpMaxE & XFracZero;
|
assign XInfE = XExpMaxE & XFracZero;
|
||||||
assign YInfE = YExpMaxE & YFracZero;
|
assign YInfE = YExpMaxE & YFracZero;
|
||||||
assign ZInfE = ZExpMaxE & ZFracZero;
|
assign ZInfE = ZExpMaxE & ZFracZero;
|
||||||
|
|
||||||
|
// is the input zero
|
||||||
assign XZeroE = XExpZero & XFracZero;
|
assign XZeroE = XExpZero & XFracZero;
|
||||||
assign YZeroE = YExpZero & YFracZero;
|
assign YZeroE = YExpZero & YFracZero;
|
||||||
assign ZZeroE = ZExpZero & ZFracZero;
|
assign ZZeroE = ZExpZero & ZFracZero;
|
||||||
|
Loading…
Reference in New Issue
Block a user