From 559c0c278e86c92a1f99de42bb9d081af942348f Mon Sep 17 00:00:00 2001 From: Katherine Parry Date: Tue, 31 May 2022 16:18:50 +0000 Subject: [PATCH 1/6] added unpackinput.sv --- addins/riscv-arch-test | 2 +- pipelined/regression/sim-fp-batch | 2 +- pipelined/src/fpu/fcvt.sv | 14 +- pipelined/src/fpu/unpack.sv | 538 +----------------------------- pipelined/src/fpu/unpackinput.sv | 402 ++++++++++++++++++++++ pipelined/src/generic/lzc.sv | 6 +- 6 files changed, 424 insertions(+), 540 deletions(-) create mode 100644 pipelined/src/fpu/unpackinput.sv diff --git a/addins/riscv-arch-test b/addins/riscv-arch-test index 307c77b26..be67c99bd 160000 --- a/addins/riscv-arch-test +++ b/addins/riscv-arch-test @@ -1 +1 @@ -Subproject commit 307c77b26e070ae85ffea665ad9b642b40e33c86 +Subproject commit be67c99bd461742aa1c100bcc0732657faae2230 diff --git a/pipelined/regression/sim-fp-batch b/pipelined/regression/sim-fp-batch index 7e2c6a341..ca0ba3d38 100755 --- a/pipelined/regression/sim-fp-batch +++ b/pipelined/regression/sim-fp-batch @@ -7,4 +7,4 @@ # sqrt - test square root # all - test everything -vsim -c -do "do fp.do rv64fp fma" \ No newline at end of file +vsim -c -do "do fp.do rv64fp cvtfp" \ No newline at end of file diff --git a/pipelined/src/fpu/fcvt.sv b/pipelined/src/fpu/fcvt.sv index bebd0ef1d..227b0098e 100644 --- a/pipelined/src/fpu/fcvt.sv +++ b/pipelined/src/fpu/fcvt.sv @@ -42,7 +42,7 @@ module fcvt ( logic [`XLEN-1:0] TrimInt; // integer trimmed to the correct size logic [`LGLEN-1:0] LzcIn; // input to the Leading Zero Counter (priority encoder) logic [`NE:0] CalcExp; // the calculated expoent - logic [$clog2(`LGLEN)-1:0] ShiftAmt; // how much to shift by + logic [$clog2(`LGLEN+1)-1:0] ShiftAmt; // how much to shift by logic [`LGLEN+`NF:0] ShiftIn; // number to be shifted logic ResDenormUf;// does the result underflow or is denormalized logic ResUf; // does the result underflow @@ -72,7 +72,7 @@ module fcvt ( logic Int64; // is the integer 64 bits? logic IntToFp; // is the opperation an int->fp conversion? logic ToInt; // is the opperation an fp->int conversion? - logic [$clog2(`LGLEN)-1:0] ZeroCnt; // output from the LZC + logic [$clog2(`LGLEN+1)-1:0] ZeroCnt; // output from the LZC // seperate OpCtrl for code readability @@ -143,9 +143,9 @@ module fcvt ( // - only shift fp -> fp if the intital value is denormalized // - this is a problem because the input to the lzc was the fraction rather than the mantissa // - rather have a few and-gates than an extra bit in the priority encoder??? *** is this true? - assign ShiftAmt = ToInt ? CalcExp[$clog2(`LGLEN)-1:0]&{$clog2(`LGLEN){~CalcExp[`NE]}} : - ResDenormUf&~IntToFp ? ($clog2(`LGLEN))'(`NF-1)+CalcExp[$clog2(`LGLEN)-1:0] : - (ZeroCnt+1)&{$clog2(`LGLEN){XDenormE|IntToFp}}; + assign ShiftAmt = ToInt ? CalcExp[$clog2(`LGLEN+1)-1:0]&{$clog2(`LGLEN+1){~CalcExp[`NE]}} : + ResDenormUf&~IntToFp ? ($clog2(`LGLEN+1))'(`NF-1)+CalcExp[$clog2(`LGLEN+1)-1:0] : + (ZeroCnt+1)&{$clog2(`LGLEN+1){XDenormE|IntToFp}}; // shift // fp -> int: | `XLEN zeros | Mantissa | 0's if nessisary | << CalcExp @@ -255,13 +255,13 @@ module fcvt ( // | keep | // // - if the input is denormalized then we dont shift... so the "- (ZeroCnt+1)" is just leftovers from other options - // int -> fp : largest bias XLEN - Largest bias + new bias - 1 - ZeroCnt = XLEN + NewBias - 1 - ZeroCnt + // int -> fp : largest bias + XLEN - Largest bias + new bias - 1 - ZeroCnt = XLEN + NewBias - 1 - ZeroCnt // Process: // - shifted right by XLEN (XLEN) // - shift left to normilize (-1-ZeroCnt) // - newBias to make the biased exponent // - assign CalcExp = {1'b0, OldExp} - (`NE+1)'(`BIAS) + {2'b0, NewBias} - {{`NE{1'b0}}, XDenormE|IntToFp} - {{`NE-$clog2(`LGLEN)+1{1'b0}}, (ZeroCnt&{$clog2(`LGLEN){XDenormE|IntToFp}})}; + assign CalcExp = {1'b0, OldExp} - (`NE+1)'(`BIAS) + {2'b0, NewBias} - {{`NE{1'b0}}, XDenormE|IntToFp} - {{`NE-$clog2(`LGLEN+1)+1{1'b0}}, (ZeroCnt&{$clog2(`LGLEN+1){XDenormE|IntToFp}})}; // find if the result is dnormal or underflows // - if Calculated expoenent is 0 or negitive (and the input/result is not exactaly 0) // - can't underflow an integer to Fp conversion diff --git a/pipelined/src/fpu/unpack.sv b/pipelined/src/fpu/unpack.sv index a10d1f8ca..9e691e27f 100644 --- a/pipelined/src/fpu/unpack.sv +++ b/pipelined/src/fpu/unpack.sv @@ -21,538 +21,20 @@ module unpack ( logic XExpZero, YExpZero, ZExpZero; // is the exponent zero logic YExpMaxE, ZExpMaxE; // is the exponent all 1s - if (`FPSIZES == 1) begin // if there is only one floating point format supported + unpackinput unpackinputX (.In(X), .FmtE, .Sgn(XSgnE), .Exp(XExpE), .Man(XManE), + .NaN(XNaNE), .SNaN(XSNaNE), .Denorm(XDenormE), + .Zero(XZeroE), .Inf(XInfE), .ExpMax(XExpMaxE), .ExpZero(XExpZero)); - // sign bit - assign XSgnE = X[`FLEN-1]; - assign YSgnE = Y[`FLEN-1]; - assign ZSgnE = Z[`FLEN-1]; + unpackinput unpackinputY (.In(Y), .FmtE, .Sgn(YSgnE), .Exp(YExpE), .Man(YManE), + .NaN(YNaNE), .SNaN(YSNaNE), .Denorm(YDenormE), + .Zero(YZeroE), .Inf(YInfE), .ExpMax(YExpMaxE), .ExpZero(YExpZero)); - // exponent - assign XExpE = {X[`FLEN-2:`NF+1], X[`NF]|XDenormE}; - assign YExpE = {Y[`FLEN-2:`NF+1], Y[`NF]|YDenormE}; - assign ZExpE = {Z[`FLEN-2:`NF+1], Z[`NF]|ZDenormE}; - - // fraction (no assumed 1) - assign XFracE = X[`NF-1:0]; - assign YFracE = Y[`NF-1:0]; - assign ZFracE = Z[`NF-1:0]; - - // is the exponent non-zero - assign XExpNonzero = |XExpE; - assign YExpNonzero = |YExpE; - assign ZExpNonzero = |ZExpE; - - // is the exponent all 1's - assign XExpMaxE = &XExpE; - assign YExpMaxE = &YExpE; - assign ZExpMaxE = &ZExpE; - - - // is the input (in it's original format) denormalized - assign XDenormE = ~|X[`FLEN-2:`NF] & ~XFracZero; - assign YDenormE = ~|Y[`FLEN-2:`NF] & ~YFracZero; - assign ZDenormE = ~|Z[`FLEN-2:`NF] & ~ZFracZero; - - - end else if (`FPSIZES == 2) begin // if there are 2 floating point formats supported - //***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 - 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 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 YSgnE = FmtE ? Y[`FLEN-1] : YLen1[`LEN1-1]; - assign ZSgnE = FmtE ? Z[`FLEN-1] : ZLen1[`LEN1-1]; - - // example double to single conversion: - // 1023 = 0011 1111 1111 - // 127 = 0000 0111 1111 (subtract this) - // 896 = 0011 1000 0000 - // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b - // dexp = 0bdd dbbb bbbb - // 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 - // - if the original precision had a denormal number convert the exponent value 1 - assign XExpE = FmtE ? {X[`FLEN-2:`NF+1], X[`NF]|XDenormE} : {XLen1[`LEN1-2], {`NE-`NE1{~XLen1[`LEN1-2]}}, XLen1[`LEN1-3:`NF1+1], XLen1[`NF1]|XDenormE}; - assign YExpE = FmtE ? {Y[`FLEN-2:`NF+1], Y[`NF]|YDenormE} : {YLen1[`LEN1-2], {`NE-`NE1{~YLen1[`LEN1-2]}}, YLen1[`LEN1-3:`NF1+1], YLen1[`NF1]|YDenormE}; - assign ZExpE = FmtE ? {Z[`FLEN-2:`NF+1], Z[`NF]|ZDenormE} : {ZLen1[`LEN1-2], {`NE-`NE1{~ZLen1[`LEN1-2]}}, ZLen1[`LEN1-3:`NF1+1], ZLen1[`NF1]|ZDenormE}; - - // is the input (in it's original format) denormalized - - // is the input (in it's original format) denormalized - assign XDenormE = (FmtE ? ~|X[`FLEN-2:`NF] : ~|XLen1[`LEN1-2:`NF1]) & ~XFracZero; - assign YDenormE = (FmtE ? ~|Y[`FLEN-2:`NF] : ~|YLen1[`LEN1-2:`NF1]) & ~YFracZero; - assign ZDenormE = (FmtE ? ~|Z[`FLEN-2:`NF] : ~|ZLen1[`LEN1-2:`NF1]) & ~ZFracZero; - - // 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 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)}; - - // is the exponent non-zero - assign XExpNonzero = FmtE ? |X[`FLEN-2:`NF] : |XLen1[`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]; - - // is the exponent all 1's - assign XExpMaxE = FmtE ? &X[`FLEN-2:`NF] : &XLen1[`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]; - - - end else if (`FPSIZES == 3) begin // three floating point precsions supported - - //***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 - for larger precision - 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 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 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)}; - - // There are 2 case statements - // - one for other singals and one for sgn/exp/frac - // - need two for the dependencies in the expoenent calculation - //*** pull out the ~FracZero and and it at the end - always_comb begin - case (FmtE) - `FMT: begin // if input is largest precision (`FLEN - ie quad or double) - - // This is the original format so set OrigDenorm to 0 - XDenormE = ~|X[`FLEN-2:`NF] & ~XFracZero; - YDenormE = ~|Y[`FLEN-2:`NF] & ~YFracZero; - ZDenormE = ~|Z[`FLEN-2:`NF] & ~ZFracZero; - - // is the exponent non-zero - XExpNonzero = |X[`FLEN-2:`NF]; - YExpNonzero = |Y[`FLEN-2:`NF]; - ZExpNonzero = |Z[`FLEN-2:`NF]; - - // is the exponent all 1's - XExpMaxE = &X[`FLEN-2:`NF]; - YExpMaxE = &Y[`FLEN-2:`NF]; - ZExpMaxE = &Z[`FLEN-2:`NF]; - end - `FMT1: begin // if input is larger precsion (`LEN1 - double or single) - - // is the input (in it's original format) denormalized - XDenormE = ~|XLen1[`LEN1-2:`NF1] & ~XFracZero; - YDenormE = ~|YLen1[`LEN1-2:`NF1] & ~YFracZero; - ZDenormE = ~|ZLen1[`LEN1-2:`NF1] & ~ZFracZero; - - // is the exponent non-zero - XExpNonzero = |XLen1[`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 - `FMT2: begin // if input is smallest precsion (`LEN2 - single or half) - - // is the input (in it's original format) denormalized - XDenormE = ~|XLen2[`LEN2-2:`NF2] & ~XFracZero; - YDenormE = ~|YLen2[`LEN2-2:`NF2] & ~YFracZero; - ZDenormE = ~|ZLen2[`LEN2-2:`NF2] & ~ZFracZero; - - // is the exponent non-zero - XExpNonzero = |XLen2[`LEN2-2:`NF2]; - YExpNonzero = |YLen2[`LEN2-2:`NF2]; - ZExpNonzero = |ZLen2[`LEN2-2:`NF2]; - - // is the exponent all 1's - XExpMaxE = &XLen2[`LEN2-2:`NF2]; - YExpMaxE = &YLen2[`LEN2-2:`NF2]; - ZExpMaxE = &ZLen2[`LEN2-2:`NF2]; - end - default: begin - XDenormE = 0; - YDenormE = 0; - ZDenormE = 0; - XExpNonzero = 0; - YExpNonzero = 0; - ZExpNonzero = 0; - XExpMaxE = 0; - YExpMaxE = 0; - ZExpMaxE = 0; - end - endcase - end - always_comb begin - case (FmtE) - `FMT: begin // if input is largest precision (`FLEN - ie quad or double) - // extract the sign bit - XSgnE = X[`FLEN-1]; - YSgnE = Y[`FLEN-1]; - ZSgnE = Z[`FLEN-1]; - - // extract the exponent - XExpE = {X[`FLEN-2:`NF+1], X[`NF]|XDenormE}; - YExpE = {Y[`FLEN-2:`NF+1], Y[`NF]|YDenormE}; - ZExpE = {Z[`FLEN-2:`NF+1], Z[`NF]|ZDenormE}; - - // extract the fraction - XFracE = X[`NF-1:0]; - YFracE = Y[`NF-1:0]; - ZFracE = Z[`NF-1:0]; - end - `FMT1: begin // if input is larger precsion (`LEN1 - double or single) - - // extract the sign bit - XSgnE = XLen1[`LEN1-1]; - YSgnE = YLen1[`LEN1-1]; - ZSgnE = ZLen1[`LEN1-1]; - - // example double to single conversion: - // 1023 = 0011 1111 1111 - // 127 = 0000 0111 1111 (subtract this) - // 896 = 0011 1000 0000 - // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b - // dexp = 0bdd dbbb bbbb - // also need to take into account possible zero/denorm/inf/NaN values - - // convert the larger precision's exponent to use the largest precision's bias - XExpE = {XLen1[`LEN1-2], {`NE-`NE1{~XLen1[`LEN1-2]}}, XLen1[`LEN1-3:`NF1+1], XLen1[`NF1]|XDenormE}; - YExpE = {YLen1[`LEN1-2], {`NE-`NE1{~YLen1[`LEN1-2]}}, YLen1[`LEN1-3:`NF1+1], YLen1[`NF1]|YDenormE}; - ZExpE = {ZLen1[`LEN1-2], {`NE-`NE1{~ZLen1[`LEN1-2]}}, ZLen1[`LEN1-3:`NF1+1], ZLen1[`NF1]|ZDenormE}; - - // extract the fraction and add the nessesary trailing zeros - XFracE = {XLen1[`NF1-1:0], (`NF-`NF1)'(0)}; - YFracE = {YLen1[`NF1-1:0], (`NF-`NF1)'(0)}; - ZFracE = {ZLen1[`NF1-1:0], (`NF-`NF1)'(0)}; - end - `FMT2: begin // if input is smallest precsion (`LEN2 - single or half) - - // exctract the sign bit - XSgnE = XLen2[`LEN2-1]; - YSgnE = YLen2[`LEN2-1]; - ZSgnE = ZLen2[`LEN2-1]; - - // example double to single conversion: - // 1023 = 0011 1111 1111 - // 127 = 0000 0111 1111 (subtract this) - // 896 = 0011 1000 0000 - // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b - // dexp = 0bdd dbbb bbbb - // also need to take into account possible zero/denorm/inf/NaN values - - // convert the smallest precision's exponent to use the largest precision's bias - XExpE = XDenormE ? {1'b0, {`NE-`NE2{1'b1}}, (`NE2-1)'(1)} : {XLen2[`LEN2-2], {`NE-`NE2{~XLen2[`LEN2-2]}}, XLen2[`LEN2-3:`NF2]}; - YExpE = YDenormE ? {1'b0, {`NE-`NE2{1'b1}}, (`NE2-1)'(1)} : {YLen2[`LEN2-2], {`NE-`NE2{~YLen2[`LEN2-2]}}, YLen2[`LEN2-3:`NF2]}; - ZExpE = ZDenormE ? {1'b0, {`NE-`NE2{1'b1}}, (`NE2-1)'(1)} : {ZLen2[`LEN2-2], {`NE-`NE2{~ZLen2[`LEN2-2]}}, ZLen2[`LEN2-3:`NF2]}; - - // extract the fraction and add the nessesary trailing zeros - XFracE = {XLen2[`NF2-1:0], (`NF-`NF2)'(0)}; - YFracE = {YLen2[`NF2-1:0], (`NF-`NF2)'(0)}; - ZFracE = {ZLen2[`NF2-1:0], (`NF-`NF2)'(0)}; - end - default: begin - XSgnE = 0; - YSgnE = 0; - ZSgnE = 0; - XExpE = 0; - YExpE = 0; - ZExpE = 0; - XFracE = 0; - YFracE = 0; - ZFracE = 0; - end - endcase - end - - end else if (`FPSIZES == 4) begin // if all precsisons are supported - quad, double, single, and half - - // quad | double | single | half - //------------------------------------------------------------------- - // `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 [`D_LEN-1:0] XLen1, YLen1, ZLen1; // Remove NaN boxing or NaN, if not properly NaN boxed for double percision - logic [`S_LEN-1:0] XLen2, YLen2, ZLen2; // Remove NaN boxing or NaN, if not properly NaN boxed for single percision - logic [`H_LEN-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 - for double precision - 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[`Q_LEN-1:`D_LEN] ? Y[`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)}; - - // Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for single precision - 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 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)}; - - // Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for half precision - 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 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)}; - - - // There are 2 case statements - // - one for other singals and one for sgn/exp/frac - // - need two for the dependencies in the expoenent calculation - always_comb begin - case (FmtE) - 2'b11: begin // if input is quad percision - - // is the input (in it's original format) denormalized - XDenormE = ~|X[`Q_LEN-2:`Q_NF] & ~XFracZero; - YDenormE = ~|Y[`Q_LEN-2:`Q_NF] & ~YFracZero; - ZDenormE = ~|Z[`Q_LEN-2:`Q_NF] & ~ZFracZero; - - // is the exponent non-zero - XExpNonzero = |X[`Q_LEN-2:`Q_NF]; - YExpNonzero = |Y[`Q_LEN-2:`Q_NF]; - ZExpNonzero = |Z[`Q_LEN-2:`Q_NF]; - - // is the exponent all 1's - XExpMaxE = &X[`Q_LEN-2:`Q_NF]; - YExpMaxE = &Y[`Q_LEN-2:`Q_NF]; - ZExpMaxE = &Z[`Q_LEN-2:`Q_NF]; - end - 2'b01: begin // if input is double percision - - // is the exponent all 1's - XExpMaxE = &XLen1[`D_LEN-2:`D_NF]; - YExpMaxE = &YLen1[`D_LEN-2:`D_NF]; - ZExpMaxE = &ZLen1[`D_LEN-2:`D_NF]; - - // is the input (in it's original format) denormalized - XDenormE = ~|XLen1[`D_LEN-2:`D_NF] & ~XFracZero; - YDenormE = ~|YLen1[`D_LEN-2:`D_NF] & ~YFracZero; - ZDenormE = ~|ZLen1[`D_LEN-2:`D_NF] & ~ZFracZero; - - // is the exponent non-zero - XExpNonzero = |XLen1[`D_LEN-2:`D_NF]; - YExpNonzero = |YLen1[`D_LEN-2:`D_NF]; - ZExpNonzero = |ZLen1[`D_LEN-2:`D_NF]; - end - 2'b00: begin // if input is single percision - - // is the exponent all 1's - XExpMaxE = &XLen2[`S_LEN-2:`S_NF]; - YExpMaxE = &YLen2[`S_LEN-2:`S_NF]; - ZExpMaxE = &ZLen2[`S_LEN-2:`S_NF]; - - // is the input (in it's original format) denormalized - XDenormE = ~|XLen2[`S_LEN-2:`S_NF] & ~XFracZero; - YDenormE = ~|YLen2[`S_LEN-2:`S_NF] & ~YFracZero; - ZDenormE = ~|ZLen2[`S_LEN-2:`S_NF] & ~ZFracZero; - - // is the exponent non-zero - XExpNonzero = |XLen2[`S_LEN-2:`S_NF]; - YExpNonzero = |YLen2[`S_LEN-2:`S_NF]; - ZExpNonzero = |ZLen2[`S_LEN-2:`S_NF]; - end - 2'b10: begin // if input is half percision - - // is the exponent all 1's - XExpMaxE = &XLen3[`H_LEN-2:`H_NF]; - YExpMaxE = &YLen3[`H_LEN-2:`H_NF]; - ZExpMaxE = &ZLen3[`H_LEN-2:`H_NF]; - - // is the input (in it's original format) denormalized - XDenormE = ~|XLen3[`H_LEN-2:`H_NF] & ~XFracZero; - YDenormE = ~|YLen3[`H_LEN-2:`H_NF] & ~YFracZero; - ZDenormE = ~|ZLen3[`H_LEN-2:`H_NF] & ~ZFracZero; - - // is the exponent non-zero - XExpNonzero = |XLen3[`H_LEN-2:`H_NF]; - YExpNonzero = |YLen3[`H_LEN-2:`H_NF]; - ZExpNonzero = |ZLen3[`H_LEN-2:`H_NF]; - end - endcase - end - - always_comb begin - case (FmtE) - 2'b11: begin // if input is quad percision - // extract sign bit - XSgnE = X[`Q_LEN-1]; - YSgnE = Y[`Q_LEN-1]; - ZSgnE = Z[`Q_LEN-1]; - - // extract the exponent - XExpE = {X[`Q_LEN-2:`Q_NF+1], X[`Q_NF]|XDenormE}; - YExpE = {Y[`Q_LEN-2:`Q_NF+1], Y[`Q_NF]|YDenormE}; - ZExpE = {Z[`Q_LEN-2:`Q_NF+1], Z[`Q_NF]|ZDenormE}; - - // extract the fraction - XFracE = X[`Q_NF-1:0]; - YFracE = Y[`Q_NF-1:0]; - ZFracE = Z[`Q_NF-1:0]; - end - 2'b01: begin // if input is double percision - // extract sign bit - XSgnE = XLen1[`D_LEN-1]; - YSgnE = YLen1[`D_LEN-1]; - ZSgnE = ZLen1[`D_LEN-1]; - - // example double to single conversion: - // 1023 = 0011 1111 1111 - // 127 = 0000 0111 1111 (subtract this) - // 896 = 0011 1000 0000 - // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b - // dexp = 0bdd dbbb bbbb - // also need to take into account possible zero/denorm/inf/NaN values - - // convert the double precsion exponent into quad precsion - - XExpE = {XLen1[`D_LEN-2], {`Q_NE-`D_NE{~XLen1[`D_LEN-2]}}, XLen1[`D_LEN-3:`D_NF+1], XLen1[`D_NF]|XDenormE}; - YExpE = {YLen1[`D_LEN-2], {`Q_NE-`D_NE{~YLen1[`D_LEN-2]}}, YLen1[`D_LEN-3:`D_NF+1], YLen1[`D_NF]|YDenormE}; - ZExpE = {ZLen1[`D_LEN-2], {`Q_NE-`D_NE{~ZLen1[`D_LEN-2]}}, ZLen1[`D_LEN-3:`D_NF+1], ZLen1[`D_NF]|ZDenormE}; - - // extract the fraction and add the nessesary trailing zeros - XFracE = {XLen1[`D_NF-1:0], (`Q_NF-`D_NF)'(0)}; - YFracE = {YLen1[`D_NF-1:0], (`Q_NF-`D_NF)'(0)}; - ZFracE = {ZLen1[`D_NF-1:0], (`Q_NF-`D_NF)'(0)}; - end - 2'b00: begin // if input is single percision - // extract sign bit - XSgnE = XLen2[`S_LEN-1]; - YSgnE = YLen2[`S_LEN-1]; - ZSgnE = ZLen2[`S_LEN-1]; - - // example double to single conversion: - // 1023 = 0011 1111 1111 - // 127 = 0000 0111 1111 (subtract this) - // 896 = 0011 1000 0000 - // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b - // dexp = 0bdd dbbb bbbb - // also need to take into account possible zero/denorm/inf/NaN values - - // convert the single precsion exponent into quad precsion - XExpE = {XLen2[`S_LEN-2], {`Q_NE-`S_NE{~XLen2[`S_LEN-2]}}, XLen2[`S_LEN-3:`S_NF+1], XLen2[`S_NF]|XDenormE}; - YExpE = {YLen2[`S_LEN-2], {`Q_NE-`S_NE{~YLen2[`S_LEN-2]}}, YLen2[`S_LEN-3:`S_NF+1], YLen2[`S_NF]|YDenormE}; - ZExpE = {ZLen2[`S_LEN-2], {`Q_NE-`S_NE{~ZLen2[`S_LEN-2]}}, ZLen2[`S_LEN-3:`S_NF+1], ZLen2[`S_NF]|ZDenormE}; - - // extract the fraction and add the nessesary trailing zeros - XFracE = {XLen2[`S_NF-1:0], (`Q_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)}; - end - 2'b10: begin // if input is half percision - // extract sign bit - XSgnE = XLen3[`H_LEN-1]; - YSgnE = YLen3[`H_LEN-1]; - ZSgnE = ZLen3[`H_LEN-1]; - - // example double to single conversion: - // 1023 = 0011 1111 1111 - // 127 = 0000 0111 1111 (subtract this) - // 896 = 0011 1000 0000 - // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b - // dexp = 0bdd dbbb bbbb - // also need to take into account possible zero/denorm/inf/NaN values - - // convert the half precsion exponent into quad precsion - XExpE = {XLen3[`H_LEN-2], {`Q_NE-`H_NE{~XLen3[`H_LEN-2]}}, XLen3[`H_LEN-3:`H_NF+1], XLen3[`H_NF]|XDenormE}; - YExpE = {YLen3[`H_LEN-2], {`Q_NE-`H_NE{~YLen3[`H_LEN-2]}}, YLen3[`H_LEN-3:`H_NF+1], YLen3[`H_NF]|YDenormE}; - ZExpE = {ZLen3[`H_LEN-2], {`Q_NE-`H_NE{~ZLen3[`H_LEN-2]}}, ZLen3[`H_LEN-3:`H_NF+1], ZLen3[`H_NF]|ZDenormE}; - - // extract the fraction and add the nessesary trailing zeros - XFracE = {XLen3[`H_NF-1:0], (`Q_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)}; - end - endcase - end - - end - - // is the exponent all 0's - assign XExpZero = ~XExpNonzero; - assign YExpZero = ~YExpNonzero; - assign ZExpZero = ~ZExpNonzero; - - // is the fraction zero - assign XFracZero = ~|XFracE; - assign YFracZero = ~|YFracE; - assign ZFracZero = ~|ZFracE; - - // add the assumed one (or zero if denormal or zero) to create the mantissa - assign XManE = {XExpNonzero, XFracE}; - assign YManE = {YExpNonzero, YFracE}; - assign ZManE = {ZExpNonzero, ZFracE}; + unpackinput unpackinputZ (.In(Z), .FmtE, .Sgn(ZSgnE), .Exp(ZExpE), .Man(ZManE), + .NaN(ZNaNE), .SNaN(ZSNaNE), .Denorm(ZDenormE), + .Zero(ZZeroE), .Inf(ZInfE), .ExpMax(ZExpMaxE), .ExpZero(ZExpZero)); + // is X normalized assign XNormE = ~(XExpMaxE|XExpZero); - // is the input a NaN - // - force to be a NaN if it isn't properly Nan Boxed - assign XNaNE = XExpMaxE & ~XFracZero; - assign YNaNE = YExpMaxE & ~YFracZero; - assign ZNaNE = ZExpMaxE & ~ZFracZero; - - // is the input a singnaling NaN - assign XSNaNE = XNaNE&~XFracE[`NF-1]; - assign YSNaNE = YNaNE&~YFracE[`NF-1]; - assign ZSNaNE = ZNaNE&~ZFracE[`NF-1]; - - // // is the input denormalized - // assign XDenormE = XExpZero & ~XFracZero; - // assign YDenormE = YExpZero & ~YFracZero; - // assign ZDenormE = ZExpZero & ~ZFracZero; - - // is the input infinity - assign XInfE = XExpMaxE & XFracZero; - assign YInfE = YExpMaxE & YFracZero; - assign ZInfE = ZExpMaxE & ZFracZero; - - // is the input zero - assign XZeroE = XExpZero & XFracZero; - assign YZeroE = YExpZero & YFracZero; - assign ZZeroE = ZExpZero & ZFracZero; - endmodule \ No newline at end of file diff --git a/pipelined/src/fpu/unpackinput.sv b/pipelined/src/fpu/unpackinput.sv new file mode 100644 index 000000000..e8bd22fbf --- /dev/null +++ b/pipelined/src/fpu/unpackinput.sv @@ -0,0 +1,402 @@ +`include "wally-config.vh" + +module unpackinput ( + input logic [`FLEN-1:0] In, // inputs from register file + input logic [`FPSIZES/3:0] FmtE, // format signal 00 - single 01 - double 11 - quad 10 - half + output logic Sgn, // sign bits of XYZ + output logic [`NE-1:0] Exp, // exponents of XYZ (converted to largest supported precision) + output logic [`NF:0] Man, // mantissas of XYZ (converted to largest supported precision) + output logic NaN, // is XYZ a NaN + output logic SNaN, // is XYZ a signaling NaN + output logic Denorm, // is XYZ denormalized + output logic Zero, // is XYZ zero + output logic Inf, // is XYZ infinity + output logic ExpMax, // does In have the maximum exponent (NaN or Inf) + output logic ExpZero // is the exponent zero +); + + logic [`NF-1:0] Frac; //Fraction of XYZ + logic ExpNonZero; // is the exponent of XYZ non-zero + logic FracZero; // is the fraction zero + + if (`FPSIZES == 1) begin // if there is only one floating point format supported + + // sign bit + assign Sgn = In[`FLEN-1]; + + // exponent + assign Exp = {In[`FLEN-2:`NF+1], In[`NF]|Denorm}; + + // fraction (no assumed 1) + assign Frac = In[`NF-1:0]; + + // is the exponent non-zero + assign ExpNonZero = |Exp; + + // is the exponent all 1's + assign ExpMax = &Exp; + + + // is the input (in it's original format) denormalized + assign Denorm = ~|In[`FLEN-2:`NF] & ~FracZero; + + + end else if (`FPSIZES == 2) begin // if there are 2 floating point formats supported + //***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] Len1; // 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 + assign Len1 = &In[`FLEN-1:`LEN1] ? In[`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 Sgn = FmtE ? In[`FLEN-1] : Len1[`LEN1-1]; + + // example double to single conversion: + // 1023 = 0011 1111 1111 + // 127 = 0000 0111 1111 (subtract this) + // 896 = 0011 1000 0000 + // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b + // dexp = 0bdd dbbb bbbb + // 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 + // - if the original precision had a denormal number convert the exponent value 1 + assign Exp = FmtE ? {In[`FLEN-2:`NF+1], In[`NF]|Denorm} : {Len1[`LEN1-2], {`NE-`NE1{~Len1[`LEN1-2]}}, Len1[`LEN1-3:`NF1+1], Len1[`NF1]|Denorm}; + + // is the input (in it's original format) denormalized + + // is the input (in it's original format) denormalized + assign Denorm = (FmtE ? ~|In[`FLEN-2:`NF] : ~|Len1[`LEN1-2:`NF1]) & ~FracZero; + + // extract the fraction, add trailing zeroes to the mantissa if nessisary + assign Frac = FmtE ? In[`NF-1:0] : {Len1[`NF1-1:0], (`NF-`NF1)'(0)}; + + // is the exponent non-zero + assign ExpNonZero = FmtE ? |In[`FLEN-2:`NF] : |Len1[`LEN1-2:`NF1]; + + // is the exponent all 1's + assign ExpMax = FmtE ? &In[`FLEN-2:`NF] : &Len1[`LEN1-2:`NF1]; + + + end else if (`FPSIZES == 3) begin // three floating point precsions supported + + //***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] Len1; // Remove NaN boxing or NaN, if not properly NaN boxed for larger percision + logic [`LEN2-1:0] Len2; // 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 - for larger precision + assign Len1 = &In[`FLEN-1:`LEN1] ? In[`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 Len2 = &In[`FLEN-1:`LEN2] ? In[`LEN2-1:0] : {1'b0, {`NE2+1{1'b1}}, (`NF2-1)'(0)}; + + // There are 2 case statements + // - one for other singals and one for sgn/exp/frac + // - need two for the dependencies in the expoenent calculation + //*** pull out the ~FracZero and and it at the end + always_comb begin + case (FmtE) + `FMT: begin // if input is largest precision (`FLEN - ie quad or double) + + // This is the original format so set OrigDenorm to 0 + Denorm = ~|In[`FLEN-2:`NF] & ~FracZero; + + // is the exponent non-zero + ExpNonZero = |In[`FLEN-2:`NF]; + + // is the exponent all 1's + ExpMax = &In[`FLEN-2:`NF]; + end + `FMT1: begin // if input is larger precsion (`LEN1 - double or single) + + // is the input (in it's original format) denormalized + Denorm = ~|Len1[`LEN1-2:`NF1] & ~FracZero; + + // is the exponent non-zero + ExpNonZero = |Len1[`LEN1-2:`NF1]; + + // is the exponent all 1's + ExpMax = &Len1[`LEN1-2:`NF1]; + end + `FMT2: begin // if input is smallest precsion (`LEN2 - single or half) + + // is the input (in it's original format) denormalized + Denorm = ~|Len2[`LEN2-2:`NF2] & ~FracZero; + + // is the exponent non-zero + ExpNonZero = |Len2[`LEN2-2:`NF2]; + + // is the exponent all 1's + ExpMax = &Len2[`LEN2-2:`NF2]; + end + default: begin + Denorm = 0; + ExpNonZero = 0; + ExpMax = 0; + end + endcase + end + always_comb begin + case (FmtE) + `FMT: begin // if input is largest precision (`FLEN - ie quad or double) + // extract the sign bit + Sgn = In[`FLEN-1]; + + // extract the exponent + Exp = {In[`FLEN-2:`NF+1], In[`NF]|Denorm}; + + // extract the fraction + Frac = In[`NF-1:0]; + end + `FMT1: begin // if input is larger precsion (`LEN1 - double or single) + + // extract the sign bit + Sgn = Len1[`LEN1-1]; + + // example double to single conversion: + // 1023 = 0011 1111 1111 + // 127 = 0000 0111 1111 (subtract this) + // 896 = 0011 1000 0000 + // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b + // dexp = 0bdd dbbb bbbb + // also need to take into account possible zero/denorm/inf/NaN values + + // convert the larger precision's exponent to use the largest precision's bias + Exp = {Len1[`LEN1-2], {`NE-`NE1{~Len1[`LEN1-2]}}, Len1[`LEN1-3:`NF1+1], Len1[`NF1]|Denorm}; + + // extract the fraction and add the nessesary trailing zeros + Frac = {Len1[`NF1-1:0], (`NF-`NF1)'(0)}; + end + `FMT2: begin // if input is smallest precsion (`LEN2 - single or half) + + // exctract the sign bit + Sgn = Len2[`LEN2-1]; + + // example double to single conversion: + // 1023 = 0011 1111 1111 + // 127 = 0000 0111 1111 (subtract this) + // 896 = 0011 1000 0000 + // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b + // dexp = 0bdd dbbb bbbb + // also need to take into account possible zero/denorm/inf/NaN values + + // convert the smallest precision's exponent to use the largest precision's bias + Exp = Denorm ? {1'b0, {`NE-`NE2{1'b1}}, (`NE2-1)'(1)} : {Len2[`LEN2-2], {`NE-`NE2{~Len2[`LEN2-2]}}, Len2[`LEN2-3:`NF2]}; + + // extract the fraction and add the nessesary trailing zeros + Frac = {Len2[`NF2-1:0], (`NF-`NF2)'(0)}; + end + default: begin + Sgn = 0; + Exp = 0; + Frac = 0; + end + endcase + end + + end else if (`FPSIZES == 4) begin // if all precsisons are supported - quad, double, single, and half + + // quad | double | single | half + //------------------------------------------------------------------- + // `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 [`D_LEN-1:0] Len1; // Remove NaN boxing or NaN, if not properly NaN boxed for double percision + logic [`S_LEN-1:0] Len2; // Remove NaN boxing or NaN, if not properly NaN boxed for single percision + logic [`H_LEN-1:0] Len3; // 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 - for double precision + assign Len1 = &In[`Q_LEN-1:`D_LEN] ? In[`D_LEN-1:0] : {1'b0, {`D_NE+1{1'b1}}, (`D_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 Len2 = &In[`Q_LEN-1:`S_LEN] ? In[`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 half precision + assign Len3 = &In[`Q_LEN-1:`H_LEN] ? In[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)}; + + + // There are 2 case statements + // - one for other singals and one for sgn/exp/frac + // - need two for the dependencies in the expoenent calculation + always_comb begin + case (FmtE) + 2'b11: begin // if input is quad percision + + // is the input (in it's original format) denormalized + Denorm = ~|In[`Q_LEN-2:`Q_NF] & ~FracZero; + + // is the exponent non-zero + ExpNonZero = |In[`Q_LEN-2:`Q_NF]; + + // is the exponent all 1's + ExpMax = &In[`Q_LEN-2:`Q_NF]; + end + 2'b01: begin // if input is double percision + + // is the exponent all 1's + ExpMax = &Len1[`D_LEN-2:`D_NF]; + + // is the input (in it's original format) denormalized + Denorm = ~|Len1[`D_LEN-2:`D_NF] & ~FracZero; + + // is the exponent non-zero + ExpNonZero = |Len1[`D_LEN-2:`D_NF]; + end + 2'b00: begin // if input is single percision + + // is the exponent all 1's + ExpMax = &Len2[`S_LEN-2:`S_NF]; + + // is the input (in it's original format) denormalized + Denorm = ~|Len2[`S_LEN-2:`S_NF] & ~FracZero; + + // is the exponent non-zero + ExpNonZero = |Len2[`S_LEN-2:`S_NF]; + end + 2'b10: begin // if input is half percision + + // is the exponent all 1's + ExpMax = &Len3[`H_LEN-2:`H_NF]; + + // is the input (in it's original format) denormalized + Denorm = ~|Len3[`H_LEN-2:`H_NF] & ~FracZero; + + // is the exponent non-zero + ExpNonZero = |Len3[`H_LEN-2:`H_NF]; + end + endcase + end + + always_comb begin + case (FmtE) + 2'b11: begin // if input is quad percision + // extract sign bit + Sgn = In[`Q_LEN-1]; + + // extract the exponent + Exp = {In[`Q_LEN-2:`Q_NF+1], In[`Q_NF]|Denorm}; + + // extract the fraction + Frac = In[`Q_NF-1:0]; + end + 2'b01: begin // if input is double percision + // extract sign bit + Sgn = Len1[`D_LEN-1]; + + // example double to single conversion: + // 1023 = 0011 1111 1111 + // 127 = 0000 0111 1111 (subtract this) + // 896 = 0011 1000 0000 + // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b + // dexp = 0bdd dbbb bbbb + // also need to take into account possible zero/denorm/inf/NaN values + + // convert the double precsion exponent into quad precsion + + Exp = {Len1[`D_LEN-2], {`Q_NE-`D_NE{~Len1[`D_LEN-2]}}, Len1[`D_LEN-3:`D_NF+1], Len1[`D_NF]|Denorm}; + + // extract the fraction and add the nessesary trailing zeros + Frac = {Len1[`D_NF-1:0], (`Q_NF-`D_NF)'(0)}; + end + 2'b00: begin // if input is single percision + // extract sign bit + Sgn = Len2[`S_LEN-1]; + + // example double to single conversion: + // 1023 = 0011 1111 1111 + // 127 = 0000 0111 1111 (subtract this) + // 896 = 0011 1000 0000 + // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b + // dexp = 0bdd dbbb bbbb + // also need to take into account possible zero/denorm/inf/NaN values + + // convert the single precsion exponent into quad precsion + Exp = {Len2[`S_LEN-2], {`Q_NE-`S_NE{~Len2[`S_LEN-2]}}, Len2[`S_LEN-3:`S_NF+1], Len2[`S_NF]|Denorm}; + + // extract the fraction and add the nessesary trailing zeros + Frac = {Len2[`S_NF-1:0], (`Q_NF-`S_NF)'(0)}; + end + 2'b10: begin // if input is half percision + // extract sign bit + Sgn = Len3[`H_LEN-1]; + + // example double to single conversion: + // 1023 = 0011 1111 1111 + // 127 = 0000 0111 1111 (subtract this) + // 896 = 0011 1000 0000 + // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b + // dexp = 0bdd dbbb bbbb + // also need to take into account possible zero/denorm/inf/NaN values + + // convert the half precsion exponent into quad precsion + Exp = {Len3[`H_LEN-2], {`Q_NE-`H_NE{~Len3[`H_LEN-2]}}, Len3[`H_LEN-3:`H_NF+1], Len3[`H_NF]|Denorm}; + + // extract the fraction and add the nessesary trailing zeros + Frac = {Len3[`H_NF-1:0], (`Q_NF-`H_NF)'(0)}; + end + endcase + end + + end + + // is the exponent all 0's + assign ExpZero = ~ExpNonZero; + + // is the fraction zero + assign FracZero = ~|Frac; + + // add the assumed one (or zero if denormal or zero) to create the mantissa + assign Man = {ExpNonZero, Frac}; + + // is the input a NaN + // - force to be a NaN if it isn't properly Nan Boxed + assign NaN = ExpMax & ~FracZero; + + // is the input a singnaling NaN + assign SNaN = NaN&~Frac[`NF-1]; + + // is the input infinity + assign Inf = ExpMax & FracZero; + + // is the input zero + assign Zero = ExpZero & FracZero; + +endmodule \ No newline at end of file diff --git a/pipelined/src/generic/lzc.sv b/pipelined/src/generic/lzc.sv index 5b1c22f91..1ce082475 100644 --- a/pipelined/src/generic/lzc.sv +++ b/pipelined/src/generic/lzc.sv @@ -1,14 +1,14 @@ //leading zero counter i.e. priority encoder module lzc #(parameter WIDTH=1) ( input logic [WIDTH-1:0] num, - output logic [$clog2(WIDTH)-1:0] ZeroCnt + output logic [$clog2(WIDTH+1)-1:0] ZeroCnt ); /* verilator lint_off CMPCONST */ - logic [$clog2(WIDTH)-1:0] i; + logic [$clog2(WIDTH+1)-1:0] i; always_comb begin i = 0; - while (~num[WIDTH-1-(32)'(i)] & $unsigned(i) <= $unsigned(($clog2(WIDTH))'(WIDTH-1))) i = i+1; // search for leading one + while (~num[WIDTH-1-(32)'(i)] & $unsigned(i) <= $unsigned(($clog2(WIDTH+1))'(WIDTH-1))) i = i+1; // search for leading one ZeroCnt = i; end /* verilator lint_on CMPCONST */ From cd7fe9af6113c48c111a586d5c132ba72e31e993 Mon Sep 17 00:00:00 2001 From: Katherine Parry Date: Tue, 31 May 2022 17:40:34 +0000 Subject: [PATCH 2/6] reorginized unpackinput signals --- pipelined/src/fpu/unpackinput.sv | 371 +++++++++++-------------------- 1 file changed, 135 insertions(+), 236 deletions(-) diff --git a/pipelined/src/fpu/unpackinput.sv b/pipelined/src/fpu/unpackinput.sv index e8bd22fbf..0b944b645 100644 --- a/pipelined/src/fpu/unpackinput.sv +++ b/pipelined/src/fpu/unpackinput.sv @@ -24,21 +24,24 @@ module unpackinput ( // sign bit assign Sgn = In[`FLEN-1]; - // exponent - assign Exp = {In[`FLEN-2:`NF+1], In[`NF]|Denorm}; - // fraction (no assumed 1) assign Frac = In[`NF-1:0]; + + // is the fraction zero + assign FracZero = ~|Frac; // is the exponent non-zero assign ExpNonZero = |Exp; + + // is the input (in it's original format) denormalized + assign Denorm = ~ExpNonZero & ~FracZero; + + // exponent + assign Exp = {In[`FLEN-2:`NF+1], In[`NF]|Denorm}; + // is the exponent all 1's assign ExpMax = &Exp; - - - // is the input (in it's original format) denormalized - assign Denorm = ~|In[`FLEN-2:`NF] & ~FracZero; end else if (`FPSIZES == 2) begin // if there are 2 floating point formats supported @@ -69,6 +72,18 @@ module unpackinput ( // choose sign bit depending on format - 1=larger precsion 0=smaller precision assign Sgn = FmtE ? In[`FLEN-1] : Len1[`LEN1-1]; + // extract the fraction, add trailing zeroes to the mantissa if nessisary + assign Frac = FmtE ? In[`NF-1:0] : {Len1[`NF1-1:0], (`NF-`NF1)'(0)}; + + // is the fraction zero + assign FracZero = ~|Frac; + + // is the exponent non-zero + assign ExpNonZero = FmtE ? |In[`FLEN-2:`NF] : |Len1[`LEN1-2:`NF1]; + + // is the input (in it's original format) denormalized + assign Denorm = ~ExpNonZero & ~FracZero; + // example double to single conversion: // 1023 = 0011 1111 1111 // 127 = 0000 0111 1111 (subtract this) @@ -80,17 +95,8 @@ module unpackinput ( // extract the exponent, converting the smaller exponent into the larger precision if nessisary // - if the original precision had a denormal number convert the exponent value 1 assign Exp = FmtE ? {In[`FLEN-2:`NF+1], In[`NF]|Denorm} : {Len1[`LEN1-2], {`NE-`NE1{~Len1[`LEN1-2]}}, Len1[`LEN1-3:`NF1+1], Len1[`NF1]|Denorm}; + - // is the input (in it's original format) denormalized - - // is the input (in it's original format) denormalized - assign Denorm = (FmtE ? ~|In[`FLEN-2:`NF] : ~|Len1[`LEN1-2:`NF1]) & ~FracZero; - - // extract the fraction, add trailing zeroes to the mantissa if nessisary - assign Frac = FmtE ? In[`NF-1:0] : {Len1[`NF1-1:0], (`NF-`NF1)'(0)}; - - // is the exponent non-zero - assign ExpNonZero = FmtE ? |In[`FLEN-2:`NF] : |Len1[`LEN1-2:`NF1]; // is the exponent all 1's assign ExpMax = FmtE ? &In[`FLEN-2:`NF] : &Len1[`LEN1-2:`NF1]; @@ -124,109 +130,66 @@ module unpackinput ( // Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for smaller precision assign Len2 = &In[`FLEN-1:`LEN2] ? In[`LEN2-1:0] : {1'b0, {`NE2+1{1'b1}}, (`NF2-1)'(0)}; - // There are 2 case statements - // - one for other singals and one for sgn/exp/frac - // - need two for the dependencies in the expoenent calculation - //*** pull out the ~FracZero and and it at the end - always_comb begin + + // extract the sign bit + always_comb case (FmtE) - `FMT: begin // if input is largest precision (`FLEN - ie quad or double) - - // This is the original format so set OrigDenorm to 0 - Denorm = ~|In[`FLEN-2:`NF] & ~FracZero; - - // is the exponent non-zero - ExpNonZero = |In[`FLEN-2:`NF]; - - // is the exponent all 1's - ExpMax = &In[`FLEN-2:`NF]; - end - `FMT1: begin // if input is larger precsion (`LEN1 - double or single) - - // is the input (in it's original format) denormalized - Denorm = ~|Len1[`LEN1-2:`NF1] & ~FracZero; - - // is the exponent non-zero - ExpNonZero = |Len1[`LEN1-2:`NF1]; - - // is the exponent all 1's - ExpMax = &Len1[`LEN1-2:`NF1]; - end - `FMT2: begin // if input is smallest precsion (`LEN2 - single or half) - - // is the input (in it's original format) denormalized - Denorm = ~|Len2[`LEN2-2:`NF2] & ~FracZero; - - // is the exponent non-zero - ExpNonZero = |Len2[`LEN2-2:`NF2]; - - // is the exponent all 1's - ExpMax = &Len2[`LEN2-2:`NF2]; - end - default: begin - Denorm = 0; - ExpNonZero = 0; - ExpMax = 0; - end + `FMT: Sgn = In[`FLEN-1]; + `FMT1: Sgn = Len1[`LEN1-1]; + `FMT2: Sgn = Len2[`LEN2-1]; + default: Sgn = 0; endcase - end - always_comb begin + + // extract the fraction + always_comb case (FmtE) - `FMT: begin // if input is largest precision (`FLEN - ie quad or double) - // extract the sign bit - Sgn = In[`FLEN-1]; - - // extract the exponent - Exp = {In[`FLEN-2:`NF+1], In[`NF]|Denorm}; - - // extract the fraction - Frac = In[`NF-1:0]; - end - `FMT1: begin // if input is larger precsion (`LEN1 - double or single) - - // extract the sign bit - Sgn = Len1[`LEN1-1]; - - // example double to single conversion: - // 1023 = 0011 1111 1111 - // 127 = 0000 0111 1111 (subtract this) - // 896 = 0011 1000 0000 - // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b - // dexp = 0bdd dbbb bbbb - // also need to take into account possible zero/denorm/inf/NaN values - - // convert the larger precision's exponent to use the largest precision's bias - Exp = {Len1[`LEN1-2], {`NE-`NE1{~Len1[`LEN1-2]}}, Len1[`LEN1-3:`NF1+1], Len1[`NF1]|Denorm}; - - // extract the fraction and add the nessesary trailing zeros - Frac = {Len1[`NF1-1:0], (`NF-`NF1)'(0)}; - end - `FMT2: begin // if input is smallest precsion (`LEN2 - single or half) - - // exctract the sign bit - Sgn = Len2[`LEN2-1]; - - // example double to single conversion: - // 1023 = 0011 1111 1111 - // 127 = 0000 0111 1111 (subtract this) - // 896 = 0011 1000 0000 - // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b - // dexp = 0bdd dbbb bbbb - // also need to take into account possible zero/denorm/inf/NaN values - - // convert the smallest precision's exponent to use the largest precision's bias - Exp = Denorm ? {1'b0, {`NE-`NE2{1'b1}}, (`NE2-1)'(1)} : {Len2[`LEN2-2], {`NE-`NE2{~Len2[`LEN2-2]}}, Len2[`LEN2-3:`NF2]}; - - // extract the fraction and add the nessesary trailing zeros - Frac = {Len2[`NF2-1:0], (`NF-`NF2)'(0)}; - end - default: begin - Sgn = 0; - Exp = 0; - Frac = 0; - end + `FMT: Frac = In[`NF-1:0]; + `FMT1: Frac = {Len1[`NF1-1:0], (`NF-`NF1)'(0)}; + `FMT2: Frac = {Len2[`NF2-1:0], (`NF-`NF2)'(0)}; + default: Frac = 0; + endcase + + // is the fraction zero + assign FracZero = ~|Frac; + + + // is the exponent non-zero + always_comb + case (FmtE) + `FMT: ExpNonZero = |In[`FLEN-2:`NF]; // if input is largest precision (`FLEN - ie quad or double) + `FMT1: ExpNonZero = |Len1[`LEN1-2:`NF1]; // if input is larger precsion (`LEN1 - double or single) + `FMT2: ExpNonZero = |Len2[`LEN2-2:`NF2]; // if input is smallest precsion (`LEN2 - single or half) + default: ExpNonZero = 0; + endcase + + // is the input (in it's original format) denormalized + assign Denorm = ~ExpNonZero & ~FracZero; + + // example double to single conversion: + // 1023 = 0011 1111 1111 + // 127 = 0000 0111 1111 (subtract this) + // 896 = 0011 1000 0000 + // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b + // dexp = 0bdd dbbb bbbb + // also need to take into account possible zero/denorm/inf/NaN values + + // convert the larger precision's exponent to use the largest precision's bias + always_comb + case (FmtE) + `FMT: Exp = {In[`FLEN-2:`NF+1], In[`NF]|Denorm}; + `FMT1: Exp = {Len1[`LEN1-2], {`NE-`NE1{~Len1[`LEN1-2]}}, Len1[`LEN1-3:`NF1+1], Len1[`NF1]|Denorm}; + `FMT2: Exp = {Len2[`LEN2-2], {`NE-`NE2{~Len2[`LEN2-2]}}, Len2[`LEN2-3:`NF2+1], Len2[`NF2]|Denorm}; + default: Exp = 0; + endcase + + // is the exponent all 1's + always_comb + case (FmtE) + `FMT: ExpMax = &In[`FLEN-2:`NF]; + `FMT1: ExpMax = &Len1[`LEN1-2:`NF1]; + `FMT2: ExpMax = &Len2[`LEN2-2:`NF2]; + default: ExpMax = 0; endcase - end end else if (`FPSIZES == 4) begin // if all precsisons are supported - quad, double, single, and half @@ -252,137 +215,73 @@ module unpackinput ( // Check NaN boxing, If the value is not properly NaN boxed, set the value to a quiet NaN - for half precision assign Len3 = &In[`Q_LEN-1:`H_LEN] ? In[`H_LEN-1:0] : {1'b0, {`H_NE+1{1'b1}}, (`H_NF-1)'(0)}; - - // There are 2 case statements - // - one for other singals and one for sgn/exp/frac - // - need two for the dependencies in the expoenent calculation - always_comb begin + // extract sign bit + always_comb case (FmtE) - 2'b11: begin // if input is quad percision - - // is the input (in it's original format) denormalized - Denorm = ~|In[`Q_LEN-2:`Q_NF] & ~FracZero; - - // is the exponent non-zero - ExpNonZero = |In[`Q_LEN-2:`Q_NF]; - - // is the exponent all 1's - ExpMax = &In[`Q_LEN-2:`Q_NF]; - end - 2'b01: begin // if input is double percision - - // is the exponent all 1's - ExpMax = &Len1[`D_LEN-2:`D_NF]; - - // is the input (in it's original format) denormalized - Denorm = ~|Len1[`D_LEN-2:`D_NF] & ~FracZero; - - // is the exponent non-zero - ExpNonZero = |Len1[`D_LEN-2:`D_NF]; - end - 2'b00: begin // if input is single percision - - // is the exponent all 1's - ExpMax = &Len2[`S_LEN-2:`S_NF]; - - // is the input (in it's original format) denormalized - Denorm = ~|Len2[`S_LEN-2:`S_NF] & ~FracZero; - - // is the exponent non-zero - ExpNonZero = |Len2[`S_LEN-2:`S_NF]; - end - 2'b10: begin // if input is half percision - - // is the exponent all 1's - ExpMax = &Len3[`H_LEN-2:`H_NF]; - - // is the input (in it's original format) denormalized - Denorm = ~|Len3[`H_LEN-2:`H_NF] & ~FracZero; - - // is the exponent non-zero - ExpNonZero = |Len3[`H_LEN-2:`H_NF]; - end + 2'b11: Sgn = In[`Q_LEN-1]; + 2'b01: Sgn = Len1[`D_LEN-1]; + 2'b00: Sgn = Len2[`S_LEN-1]; + 2'b10: Sgn = Len3[`H_LEN-1]; endcase - end + - always_comb begin + // extract the fraction + always_comb case (FmtE) - 2'b11: begin // if input is quad percision - // extract sign bit - Sgn = In[`Q_LEN-1]; - - // extract the exponent - Exp = {In[`Q_LEN-2:`Q_NF+1], In[`Q_NF]|Denorm}; - - // extract the fraction - Frac = In[`Q_NF-1:0]; - end - 2'b01: begin // if input is double percision - // extract sign bit - Sgn = Len1[`D_LEN-1]; - - // example double to single conversion: - // 1023 = 0011 1111 1111 - // 127 = 0000 0111 1111 (subtract this) - // 896 = 0011 1000 0000 - // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b - // dexp = 0bdd dbbb bbbb - // also need to take into account possible zero/denorm/inf/NaN values - - // convert the double precsion exponent into quad precsion - - Exp = {Len1[`D_LEN-2], {`Q_NE-`D_NE{~Len1[`D_LEN-2]}}, Len1[`D_LEN-3:`D_NF+1], Len1[`D_NF]|Denorm}; - - // extract the fraction and add the nessesary trailing zeros - Frac = {Len1[`D_NF-1:0], (`Q_NF-`D_NF)'(0)}; - end - 2'b00: begin // if input is single percision - // extract sign bit - Sgn = Len2[`S_LEN-1]; - - // example double to single conversion: - // 1023 = 0011 1111 1111 - // 127 = 0000 0111 1111 (subtract this) - // 896 = 0011 1000 0000 - // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b - // dexp = 0bdd dbbb bbbb - // also need to take into account possible zero/denorm/inf/NaN values - - // convert the single precsion exponent into quad precsion - Exp = {Len2[`S_LEN-2], {`Q_NE-`S_NE{~Len2[`S_LEN-2]}}, Len2[`S_LEN-3:`S_NF+1], Len2[`S_NF]|Denorm}; - - // extract the fraction and add the nessesary trailing zeros - Frac = {Len2[`S_NF-1:0], (`Q_NF-`S_NF)'(0)}; - end - 2'b10: begin // if input is half percision - // extract sign bit - Sgn = Len3[`H_LEN-1]; - - // example double to single conversion: - // 1023 = 0011 1111 1111 - // 127 = 0000 0111 1111 (subtract this) - // 896 = 0011 1000 0000 - // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b - // dexp = 0bdd dbbb bbbb - // also need to take into account possible zero/denorm/inf/NaN values - - // convert the half precsion exponent into quad precsion - Exp = {Len3[`H_LEN-2], {`Q_NE-`H_NE{~Len3[`H_LEN-2]}}, Len3[`H_LEN-3:`H_NF+1], Len3[`H_NF]|Denorm}; - - // extract the fraction and add the nessesary trailing zeros - Frac = {Len3[`H_NF-1:0], (`Q_NF-`H_NF)'(0)}; - end + 2'b11: Frac = In[`Q_NF-1:0]; + 2'b01: Frac = {Len1[`D_NF-1:0], (`Q_NF-`D_NF)'(0)}; + 2'b00: Frac = {Len2[`S_NF-1:0], (`Q_NF-`S_NF)'(0)}; + 2'b10: Frac = {Len3[`H_NF-1:0], (`Q_NF-`H_NF)'(0)}; + endcase + + // is the fraction zero + assign FracZero = ~|Frac; + + // is the exponent non-zero + always_comb + case (FmtE) + 2'b11: ExpNonZero = |In[`Q_LEN-2:`Q_NF]; + 2'b01: ExpNonZero = |Len1[`D_LEN-2:`D_NF]; + 2'b00: ExpNonZero = |Len2[`S_LEN-2:`S_NF]; + 2'b10: ExpNonZero = |Len3[`H_LEN-2:`H_NF]; + endcase + + // is the input (in it's original format) denormalized + assign Denorm = ~ExpNonZero & ~FracZero; + + + // example double to single conversion: + // 1023 = 0011 1111 1111 + // 127 = 0000 0111 1111 (subtract this) + // 896 = 0011 1000 0000 + // sexp = 0000 bbbb bbbb (add this) b = bit d = ~b + // dexp = 0bdd dbbb bbbb + // also need to take into account possible zero/denorm/inf/NaN values + + // convert the double precsion exponent into quad precsion + always_comb + case (FmtE) + 2'b11: Exp = {In[`Q_LEN-2:`Q_NF+1], In[`Q_NF]|Denorm}; + 2'b01: Exp = {Len1[`D_LEN-2], {`Q_NE-`D_NE{~Len1[`D_LEN-2]}}, Len1[`D_LEN-3:`D_NF+1], Len1[`D_NF]|Denorm}; + 2'b00: Exp = {Len2[`S_LEN-2], {`Q_NE-`S_NE{~Len2[`S_LEN-2]}}, Len2[`S_LEN-3:`S_NF+1], Len2[`S_NF]|Denorm}; + 2'b10: Exp = {Len3[`H_LEN-2], {`Q_NE-`H_NE{~Len3[`H_LEN-2]}}, Len3[`H_LEN-3:`H_NF+1], Len3[`H_NF]|Denorm}; + endcase + + + // is the exponent all 1's + always_comb + case (FmtE) + 2'b11: ExpMax = &In[`Q_LEN-2:`Q_NF]; + 2'b01: ExpMax = &Len1[`D_LEN-2:`D_NF]; + 2'b00: ExpMax = &Len2[`S_LEN-2:`S_NF]; + 2'b10: ExpMax = &Len3[`H_LEN-2:`H_NF]; endcase - end end // is the exponent all 0's assign ExpZero = ~ExpNonZero; - // is the fraction zero - assign FracZero = ~|Frac; - // add the assumed one (or zero if denormal or zero) to create the mantissa assign Man = {ExpNonZero, Frac}; From 4bbacd3742254ada1ee591c6a9ad7466fd9a9674 Mon Sep 17 00:00:00 2001 From: DTowersM Date: Tue, 31 May 2022 20:05:51 +0000 Subject: [PATCH 3/6] dummy start trigger and stop trigger support for make file --- benchmarks/embench/Makefile | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/benchmarks/embench/Makefile b/benchmarks/embench/Makefile index 28b012cd9..0cb54e1a1 100644 --- a/benchmarks/embench/Makefile +++ b/benchmarks/embench/Makefile @@ -1,4 +1,5 @@ # Makefile added 1/20/22 David_Harris@hmc.edu +# Expanded and developed by dtorres@hmc.edu # Compile Embench for Wally all: build sim @@ -6,9 +7,9 @@ all: build sim allClean: clean all build: - ../../addins/embench-iot/build_all.py --builddir=bd_speed --arch riscv32 --chip generic --board rv32wallyverilog --ldflags="-nostartfiles ../../../config/riscv32/boards/rv32wallyverilog/startup/crt0.S" --cflags="-nostartfiles" + ../../addins/embench-iot/build_all.py -v --builddir=bd_speed --arch riscv32 --chip generic --board rv32wallyverilog --ldflags="-nostartfiles ../../../config/riscv32/boards/rv32wallyverilog/startup/crt0.S" --cflags="-nostartfiles" find ../../addins/embench-iot/bd_speed/ -type f ! -name "*.*" | while read f; do cp "$$f" "$$f.elf"; done - ../../addins/embench-iot/build_all.py --builddir=bd_size --arch riscv32 --chip generic --board rv32wallyverilog --ldflags="-nostdlib -nostartfiles" --cflags="-msave-restore" --dummy-libs="libgcc libm libc crt0" + ../../addins/embench-iot/build_all.py -v --builddir=bd_size --arch riscv32 --chip generic --board rv32wallyverilog --ldflags="-nostdlib -nostartfiles ../../../config/riscv32/boards/rv32wallyverilog/startup/dummy.S" --cflags="-msave-restore" --dummy-libs="libgcc libm libc crt0" sim: modelSimBuild size speed @@ -20,10 +21,10 @@ size: ../../addins/embench-iot/benchmark_size.py --builddir=bd_size speed: - ../../addins/embench-iot/benchmark_speed.py --builddir=bd_speed --target-module run_wally --cpu-mhz=50 + ../../addins/embench-iot/benchmark_speed.py --builddir=bd_speed --target-module run_wally --cpu-mhz=1 objdump: - find ../../addins/embench-iot/bd_speed/ -type f -name "*.elf" | while read f; do riscv64-unknown-elf-objdump -S "$$f" > "$$f.objdump"; done + find ../../addins/embench-iot/bd_speed/ -type f -name "*.elf" | while read f; do riscv64-unknown-elf-objdump -S -D "$$f" > "$$f.objdump"; done clean: rm -rf ../../addins/embench-iot/bd_speed/ @@ -37,3 +38,5 @@ clean: # ../../addins/embench-iot/build_all.py --arch riscv32 --chip generic --board rv32wallyverilog --cc riscv64-unknown-elf-gcc --cflags="-c -Os -ffunction-sections -nostdlib -march=rv32imac -mabi=ilp32" --ldflags="-Wl,-gc-sections -nostdlib -march=rv32imac -mabi=ilp32 -T../../../config/riscv32/boards/rv32wallyverilog/link.ld" --dummy-libs="libgcc libm libc" # --user-libs="-lm" # riscv64-unknown-elf-gcc -O2 -g -nostartfiles -I/home/harris/riscv-wally/addins/embench-iot/support -I/home/harris/riscv-wally/addins/embench-iot/config/riscv32/boards/ri5cyverilator -I/home/harris/riscv-wally/addins/embench-iot/config/riscv32/chips/generic -I/home/harris/riscv-wally/addins/embench-iot/config/riscv32 -DCPU_MHZ=1 -DWARMUP_HEAT=1 -o main.o /home/harris/riscv-wally/addins/embench-iot/support/main.c + +# find ../../addins/embench-iot/bd_speed/ -type f -name "*.elf.objdump.lab" | while read f; do grep -n "begin_signature" $f | cut -f1 -d: From ea07588999cb4b233fe72ec8cac19436122aa1ce Mon Sep 17 00:00:00 2001 From: DTowersM Date: Tue, 31 May 2022 20:08:04 +0000 Subject: [PATCH 4/6] added embench tests to tests.vh --- pipelined/testbench/tests.vh | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/pipelined/testbench/tests.vh b/pipelined/testbench/tests.vh index dba197f5f..d907d9a2f 100644 --- a/pipelined/testbench/tests.vh +++ b/pipelined/testbench/tests.vh @@ -28,6 +28,7 @@ `define WALLYTEST "2" `define MYIMPERASTEST "3" `define COREMARK "4" +`define EMBENCH "5" // *** remove MYIMPERASTEST cases when ported string tvpaths[] = '{ @@ -35,15 +36,44 @@ string tvpaths[] = '{ "../../addins/riscv-arch-test/work/", "../../tests/wally-riscv-arch-test/work/", "../../tests/imperas-riscv-tests/work/", - "../../benchmarks/riscv-coremark/work/" + "../../benchmarks/riscv-coremark/work/", + "../../addins/embench-iot/bd_speed/src/" }; + + // *** make sure these are somewhere string coremark[] = '{ `COREMARK, "coremark.bare.riscv", "100000" }; + string embench[] = '{ + `EMBENCH, + "aha-mont64/aha-mont64", "1080", + "crc32/crc32", "1080", + "cubic/cubic", "9080", + "edn/edn", "1080", + "huffbench/huffbench", "5080", + "matmult-int/matmult-int", "1080", + "md5sum/md5sum", "4080", + "minver/minver", "2080", + "nbody/nbody", "2080", + "nettle-aes/nettle-aes", "1080", + "nettle-sha256/nettle-sha256", "2080", + "nsichneu/nsichneu", "4080", + "picojpeg/picojpeg", "3080", + "primecount/primecount", "1080", + "qrduino/qrduino", "6080", + "sglib-combined/sglib-combined", "5080", + "slre/slre", "1080", + "st/st", "2080", + "statemate/statemate", "2080", + "tarfind/tarfind", "4080", + "ud/ud", "1080", + "wikisort/wikisort", "3080" + }; + string wally64a[] = '{ `WALLYTEST, "rv64i_m/privilege/WALLY-amo", "2210", From abb6ba97cf75bfe7931b6ed9dd0fa8e5755fddef Mon Sep 17 00:00:00 2001 From: DTowersM Date: Tue, 31 May 2022 20:09:48 +0000 Subject: [PATCH 5/6] removed delapidated signals SIE_REGW SIP_REGW TimerIntM SwIntM --- pipelined/regression/wave.do | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pipelined/regression/wave.do b/pipelined/regression/wave.do index de6eb166c..ab6cbc46a 100644 --- a/pipelined/regression/wave.do +++ b/pipelined/regression/wave.do @@ -76,8 +76,6 @@ add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/PMPCFG_ARRAY_RE add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/SATP_REGW add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/SCOUNTEREN_REGW add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/SEPC_REGW -add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/SIE_REGW -add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/SIP_REGW add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/SSTATUS_REGW add wave -noupdate -group CSRs /testbench/dut/core/priv/priv/csr/STVEC_REGW add wave -noupdate -group Bpred -color Orange /testbench/dut/core/ifu/bpred/bpred/Predictor/DirPredictor/GHR @@ -420,8 +418,6 @@ add wave -noupdate -group CLINT /testbench/dut/uncore/clint/clint/HRESPCLINT add wave -noupdate -group CLINT /testbench/dut/uncore/clint/clint/HREADYCLINT add wave -noupdate -group CLINT /testbench/dut/uncore/clint/clint/MTIME add wave -noupdate -group CLINT /testbench/dut/uncore/clint/clint/MTIMECMP -add wave -noupdate -group CLINT /testbench/dut/uncore/clint/clint/TimerIntM -add wave -noupdate -group CLINT /testbench/dut/uncore/clint/clint/SwIntM add wave -noupdate -group uart -expand -group {Bus Connection} /testbench/dut/uncore/uart/uart/HCLK add wave -noupdate -group uart -expand -group {Bus Connection} /testbench/dut/uncore/uart/uart/HRESETn add wave -noupdate -group uart -expand -group {Bus Connection} /testbench/dut/uncore/uart/uart/HSELUART From 2088c0cd7cfc1bc30e98f34e81c1b1c65c2e4d45 Mon Sep 17 00:00:00 2001 From: DTowersM Date: Tue, 31 May 2022 20:13:32 +0000 Subject: [PATCH 6/6] added testbench.sv support for embench tests, test output still WIP --- pipelined/testbench/testbench.sv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pipelined/testbench/testbench.sv b/pipelined/testbench/testbench.sv index fb338848c..ba3122926 100644 --- a/pipelined/testbench/testbench.sv +++ b/pipelined/testbench/testbench.sv @@ -119,6 +119,7 @@ logic [3:0] dummy; "wally32i": tests = wally32i; // *** redo "wally32e": tests = wally32e; "wally32priv": tests = wally32priv; // *** redo + "embench": tests = embench; endcase end if (tests.size() == 0) begin @@ -127,7 +128,7 @@ logic [3:0] dummy; end end - string signame, memfilename, pathname; + string signame, memfilename, pathname, objdumpfilename, adrstr; logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn; logic UARTSin, UARTSout;