Merge branch 'main' of github.com:openhwgroup/cvw

This commit is contained in:
Jacob Pease 2023-08-01 10:47:59 -05:00
commit 923427490e
30 changed files with 467 additions and 474 deletions

View File

@ -159,4 +159,4 @@ localparam ZBS_SUPPORTED = 0;
// Memory synthesis configuration // Memory synthesis configuration
localparam USE_SRAM = 0; localparam USE_SRAM = 0;
`include "test-shared.vh" `include "config-shared.vh"

View File

@ -172,4 +172,4 @@ localparam ZBS_SUPPORTED = 1;
// Memory synthesis configuration // Memory synthesis configuration
localparam USE_SRAM = 0; localparam USE_SRAM = 0;
`include "test-shared.vh" `include "config-shared.vh"

View File

@ -160,5 +160,5 @@ localparam ZBS_SUPPORTED = 0;
// Memory synthesis configuration // Memory synthesis configuration
localparam USE_SRAM = 0; localparam USE_SRAM = 0;
`include "test-shared.vh" `include "config-shared.vh"

View File

@ -161,4 +161,4 @@ localparam ZBS_SUPPORTED = 1;
// Memory synthesis configuration // Memory synthesis configuration
localparam USE_SRAM = 0; localparam USE_SRAM = 0;
`include "test-shared.vh" `include "config-shared.vh"

View File

@ -160,4 +160,4 @@ localparam ZBS_SUPPORTED = 0;
// Memory synthesis configuration // Memory synthesis configuration
localparam USE_SRAM = 0; localparam USE_SRAM = 0;
`include "test-shared.vh" `include "config-shared.vh"

View File

@ -159,4 +159,4 @@ localparam ZBS_SUPPORTED = 0;
// Memory synthesis configuration // Memory synthesis configuration
localparam USE_SRAM = 0; localparam USE_SRAM = 0;
`include "test-shared.vh" `include "config-shared.vh"

View File

@ -162,4 +162,4 @@ localparam ZBS_SUPPORTED = 0;
// Memory synthesis configuration // Memory synthesis configuration
localparam USE_SRAM = 0; localparam USE_SRAM = 0;
`include "test-shared.vh" `include "config-shared.vh"

View File

@ -165,4 +165,4 @@ localparam ZBS_SUPPORTED = 1;
// Memory synthesis configuration // Memory synthesis configuration
localparam USE_SRAM = 0; localparam USE_SRAM = 0;
`include "test-shared.vh" `include "config-shared.vh"

View File

@ -162,4 +162,4 @@ localparam ZBS_SUPPORTED = 0;
// Memory synthesis configuration // Memory synthesis configuration
localparam USE_SRAM = 0; localparam USE_SRAM = 0;
`include "test-shared.vh" `include "config-shared.vh"

View File

@ -112,8 +112,6 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
assign Xfract = (IFX << ell) << 1; assign Xfract = (IFX << ell) << 1;
assign Dfract = (IFD << mE) << 1; assign Dfract = (IFD << mE) << 1;
// *** CT: move to fdivsqrtintpreshift
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
// Integer Right Shift to digit boundary // Integer Right Shift to digit boundary
// Determine DivXShifted (X shifted to digit boundary) // Determine DivXShifted (X shifted to digit boundary)
@ -152,14 +150,14 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
assign ISpecialCaseE = 0; assign ISpecialCaseE = 0;
end end
// CT *** fdivsqrtfplead1
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
// Floating-Point Preprocessing // Floating-Point Preprocessing
// append leading 1 (for nonzero inputs) // append leading 1 (for nonzero inputs)
// shift square root to be in range [1/4, 1) // shift square root to be in range [1/4, 1)
// Normalized numbers are shifted right by 1 if the exponent is odd // Normalized numbers are shifted right by 1 if the exponent is odd
// Denormalized numbers have Xe = 0 and an unbiased exponent of 1-BIAS. They are shifted right if the number of leading zeros is odd. // Subnormal numbers have Xe = 0 and an unbiased exponent of 1-BIAS. They are shifted right if the number of leading zeros is odd.
// NOTE: there might be a discrepancy that X is never right shifted by 2. However
// it comes out in the wash and gives the right answer. Investigate later if possible.
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
assign DivX = {3'b000, ~NumerZeroE, Xfract}; assign DivX = {3'b000, ~NumerZeroE, Xfract};

View File

@ -67,7 +67,6 @@ module fma import cvw::*; #(parameter cvw_t P) (
// - Multiply the mantissas // - Multiply the mantissas
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// calculate the product's exponent // calculate the product's exponent
fmaexpadd #(P) expadd(.Xe, .Ye, .XZero, .YZero, .Pe); fmaexpadd #(P) expadd(.Xe, .Ye, .XZero, .YZero, .Pe);
@ -80,6 +79,7 @@ module fma import cvw::*; #(parameter cvw_t P) (
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Alignment shifter // Alignment shifter
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
fmaalign #(P) align(.Ze, .Zm, .XZero, .YZero, .ZZero, .Xe, .Ye, .Am, .ASticky, .KillProd); fmaalign #(P) align(.Ze, .Zm, .XZero, .YZero, .ZZero, .Xe, .Ye, .Am, .ASticky, .KillProd);
// /////////////////////////////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////////////////////////////
@ -91,5 +91,3 @@ module fma import cvw::*; #(parameter cvw_t P) (
fmalza #(3*P.NF+4, P.NF) lza(.A(AmInv), .Pm(PmKilled), .Cin(InvA & (~ASticky | KillProd)), .sub(InvA), .SCnt); fmalza #(3*P.NF+4, P.NF) lza(.A(AmInv), .Pm(PmKilled), .Cin(InvA & (~ASticky | KillProd)), .sub(InvA), .SCnt);
endmodule endmodule

View File

@ -1,4 +1,3 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// fmaalign.sv // fmaalign.sv
// //
@ -30,7 +29,7 @@
module fmaalign import cvw::*; #(parameter cvw_t P) ( module fmaalign import cvw::*; #(parameter cvw_t P) (
input logic [P.NE-1:0] Xe, Ye, Ze, // biased exponents in B(NE.0) format input logic [P.NE-1:0] Xe, Ye, Ze, // biased exponents in B(NE.0) format
input logic [P.NF:0] Zm, // significand in U(0.NF) format] input logic [P.NF:0] Zm, // significand in U(0.NF) format]
input logic XZero, YZero, ZZero,// is the input zero input logic XZero, YZero, ZZero, // is the input zero
output logic [3*P.NF+3:0] Am, // addend aligned for addition in U(NF+5.2NF+1) output logic [3*P.NF+3:0] Am, // addend aligned for addition in U(NF+5.2NF+1)
output logic ASticky, // Sticky bit calculated from the aliged addend output logic ASticky, // Sticky bit calculated from the aliged addend
output logic KillProd // should the product be set to zero output logic KillProd // should the product be set to zero
@ -51,18 +50,16 @@ module fmaalign import cvw::*; #(parameter cvw_t P) (
// This could have been done using Pe, but ACnt is on the critical path so we replicate logic for speed // This could have been done using Pe, but ACnt is on the critical path so we replicate logic for speed
assign ACnt = {2'b0, Xe} + {2'b0, Ye} - {2'b0, (P.NE)'(P.BIAS)} + (P.NE+2)'(P.NF+2) - {2'b0, Ze}; assign ACnt = {2'b0, Xe} + {2'b0, Ye} - {2'b0, (P.NE)'(P.BIAS)} + (P.NE+2)'(P.NF+2) - {2'b0, Ze};
// Defualt Addition with only inital left shift // Default Addition with only inital left shift
// | 53'b0 | 106'b(product) | 1'b0 | // | 53'b0 | 106'b(product) | 1'b0 |
// | addnend | // | addnend |
assign ZmPreshifted = {Zm,(3*P.NF+3)'(0)}; assign ZmPreshifted = {Zm,(3*P.NF+3)'(0)};
assign KillProd = (ACnt[P.NE+1]&~ZZero)|XZero|YZero; assign KillProd = (ACnt[P.NE+1]&~ZZero)|XZero|YZero;
assign KillZ = $signed(ACnt)>$signed((P.NE+2)'(3)*(P.NE+2)'(P.NF)+(P.NE+2)'(3)); assign KillZ = $signed(ACnt)>$signed((P.NE+2)'(3)*(P.NE+2)'(P.NF)+(P.NE+2)'(3));
always_comb begin always_comb begin
// If the product is too small to effect the sum, kill the product // If the product is too small to effect the sum, kill the product
// | 53'b0 | 106'b(product) | 1'b0 | // | 53'b0 | 106'b(product) | 1'b0 |
// | addnend | // | addnend |
if (KillProd) begin if (KillProd) begin
@ -85,11 +82,9 @@ module fmaalign import cvw::*; #(parameter cvw_t P) (
end else begin end else begin
ZmShifted = ZmPreshifted >> ACnt; ZmShifted = ZmPreshifted >> ACnt;
ASticky = |(ZmShifted[P.NF-1:0]); ASticky = |(ZmShifted[P.NF-1:0]);
end end
end end
assign Am = ZmShifted[4*P.NF+3:P.NF]; assign Am = ZmShifted[4*P.NF+3:P.NF];
endmodule endmodule

View File

@ -44,7 +44,7 @@ module fmalza #(WIDTH, NF) (
assign P = A^B; assign P = A^B;
assign G = A&B; assign G = A&B;
assign K= ~A&~B; assign K = ~A&~B;
assign Pp1 = {sub, P[WIDTH-1:1]}; // shift P right by 1 (for P_i+1) , use subtract flag in most significant bit assign Pp1 = {sub, P[WIDTH-1:1]}; // shift P right by 1 (for P_i+1) , use subtract flag in most significant bit
assign Gm1 = {G[WIDTH-2:0], Cin}; // shift G left by 1 (for G_i-1) and bring in Cin assign Gm1 = {G[WIDTH-2:0], Cin}; // shift G left by 1 (for G_i-1) and bring in Cin

View File

@ -33,4 +33,3 @@ module fmamult import cvw::*; #(parameter cvw_t P) (
assign Pm = Xm * Ym; assign Pm = Xm * Ym;
endmodule endmodule

View File

@ -47,7 +47,7 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
// seclect the input to the shifter // seclect the input to the shifter
// fp -> int: // fp -> int:
// | P.XLEN zeros | mantissa | 0's if nessisary | // | P.XLEN zeros | mantissa | 0's if necessary |
// . // .
// Other problems: // Other problems:
// - if shifting to the right (neg CalcExp) then don't a 1 in the round bit (to prevent an incorrect plus 1 later durring rounding) // - if shifting to the right (neg CalcExp) then don't a 1 in the round bit (to prevent an incorrect plus 1 later durring rounding)
@ -58,7 +58,7 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
// | P.NF-1 zeros | mantissa | 0's if nessisary | // | P.NF-1 zeros | mantissa | 0's if nessisary |
// . // .
// - otherwise: // - otherwise:
// | LzcInM | 0's if nessisary | // | LzcInM | 0's if necessary |
// . // .
// change to int shift to the left one // change to int shift to the left one
always_comb always_comb
@ -95,8 +95,6 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
endcase endcase
end end
// determine if the result underflows ??? -> fp // determine if the result underflows ??? -> fp
// - if the first 1 is shifted out of the result then the result underflows // - if the first 1 is shifted out of the result then the result underflows
// - can't underflow an integer to fp conversions // - can't underflow an integer to fp conversions

View File

@ -120,7 +120,6 @@ module flags import cvw::*; #(parameter cvw_t P) (
assign ShiftGtIntSz = (|FullRe[P.Q_NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64)); assign ShiftGtIntSz = (|FullRe[P.Q_NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64));
end end
// calulate overflow flag: // calulate overflow flag:
// if the result is greater than or equal to the max exponent(not taking into account sign) // if the result is greater than or equal to the max exponent(not taking into account sign)
// | and the exponent isn't negitive // | and the exponent isn't negitive
@ -142,7 +141,6 @@ module flags import cvw::*; #(parameter cvw_t P) (
// | | | | | | // | | | | | |
assign Underflow = ((FullRe[P.NE+1] | (FullRe == 0) | ((FullRe == 1) & (Me == 0) & ~(UfPlus1&Guard)))&(Round|Sticky|Guard))&~(InfIn|NaNIn|DivByZero|Invalid); assign Underflow = ((FullRe[P.NE+1] | (FullRe == 0) | ((FullRe == 1) & (Me == 0) & ~(UfPlus1&Guard)))&(Round|Sticky|Guard))&~(InfIn|NaNIn|DivByZero|Invalid);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Inexact // Inexact
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -199,7 +197,6 @@ module flags import cvw::*; #(parameter cvw_t P) (
// - don't set flag if an input is NaN or Inf(IEEE says has to be a finite numerator) // - don't set flag if an input is NaN or Inf(IEEE says has to be a finite numerator)
assign DivByZero = YZero&DivOp&~Sqrt&~(XZero|NaNIn|InfIn); assign DivByZero = YZero&DivOp&~Sqrt&~(XZero|NaNIn|InfIn);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// final flags // final flags
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -209,7 +206,3 @@ module flags import cvw::*; #(parameter cvw_t P) (
assign PostProcFlg = {Invalid|(IntInvalid&CvtOp&ToInt), DivByZero, Overflow&~(ToInt&CvtOp), Underflow&~(ToInt&CvtOp), Inexact}; assign PostProcFlg = {Invalid|(IntInvalid&CvtOp&ToInt), DivByZero, Overflow&~(ToInt&CvtOp), Underflow&~(ToInt&CvtOp), Inexact};
endmodule endmodule

View File

@ -27,22 +27,22 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
// convert shift // convert shift
// fp -> int: | `XLEN zeros | Mantissa | 0's if nessisary | << CalcExp // fp -> int: | `XLEN zeros | Mantissa | 0's if necessary | << CalcExp
// process: // process:
// - start - CalcExp = 1 + XExp - Largest Bias // - start - CalcExp = 1 + XExp - Largest Bias
// | `XLEN zeros | Mantissa | 0's if nessisary | // | `XLEN zeros | Mantissa | 0's if necessary |
// //
// - shift left 1 (1) // - shift left 1 (1)
// | `XLEN-1 zeros |bit| frac | 0's if nessisary | // | `XLEN-1 zeros |bit| frac | 0's if necessary |
// . <- binary point // . <- binary point
// //
// - shift left till unbiased exponent is 0 (XExp - Largest Bias) // - shift left till unbiased exponent is 0 (XExp - Largest Bias)
// | 0's | Mantissa | 0's if nessisary | // | 0's | Mantissa | 0's if necessary |
// | keep | // | keep |
// //
// fp -> fp: // fp -> fp:
// - if result is subnormal or underflowed: // - if result is subnormal or underflowed:
// | `NF-1 zeros | Mantissa | 0's if nessisary | << NF+CalcExp-1 // | `NF-1 zeros | Mantissa | 0's if necessary | << NF+CalcExp-1
// process: // process:
// - start // - start
// | mantissa | 0's | // | mantissa | 0's |
@ -55,10 +55,10 @@
// | keep | // | keep |
// //
// - if the input is subnormal: // - if the input is subnormal:
// | lzcIn | 0's if nessisary | << ZeroCnt+1 // | lzcIn | 0's if necessary | << ZeroCnt+1
// - plus 1 to shift out the first 1 // - plus 1 to shift out the first 1
// //
// int -> fp: | lzcIn | 0's if nessisary | << ZeroCnt+1 // int -> fp: | lzcIn | 0's if necessary | << ZeroCnt+1
// - plus 1 to shift out the first 1 // - plus 1 to shift out the first 1
// fma shift // fma shift

View File

@ -54,13 +54,13 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
input logic CvtCs, // the result's sign input logic CvtCs, // the result's sign
input logic [P.NE:0] CvtCe, // the calculated expoent input logic [P.NE:0] CvtCe, // the calculated expoent
input logic CvtResSubnormUf, // the convert result is subnormal or underflows input logic CvtResSubnormUf, // the convert result is subnormal or underflows
input logic [P.LOGCVTLEN-1:0] CvtShiftAmt,// how much to shift by input logic [P.LOGCVTLEN-1:0] CvtShiftAmt, // how much to shift by
input logic ToInt, // is fp->int (since it's writting to the integer register) input logic ToInt, // is fp->int (since it's writting to the integer register)
input logic [P.CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb) input logic [P.CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb)
input logic IntZero, // is the integer input zero input logic IntZero, // is the integer input zero
// final results // final results
output logic [P.FLEN-1:0] PostProcRes,// postprocessor final result output logic [P.FLEN-1:0] PostProcRes, // postprocessor final result
output logic [4:0] PostProcFlg,// postprocesser flags output logic [4:0] PostProcFlg, // postprocesser flags
output logic [P.XLEN-1:0] FCvtIntRes // the integer conversion result output logic [P.XLEN-1:0] FCvtIntRes // the integer conversion result
); );
@ -87,7 +87,7 @@ module postprocess import cvw::*; #(parameter cvw_t P) (
logic [3*P.NF+5:0] FmaShiftIn; // fma shift input logic [3*P.NF+5:0] FmaShiftIn; // fma shift input
logic [P.NE+1:0] NormSumExp; // exponent of the normalized sum not taking into account Subnormal or zero results logic [P.NE+1:0] NormSumExp; // exponent of the normalized sum not taking into account Subnormal or zero results
logic FmaPreResultSubnorm; // is the result subnormal - calculated before LZA corection logic FmaPreResultSubnorm; // is the result subnormal - calculated before LZA corection
logic [$clog2(3*P.NF+5)-1:0] FmaShiftAmt;// normalization shift amount for fma logic [$clog2(3*P.NF+5)-1:0] FmaShiftAmt; // normalization shift amount for fma
// division singals // division singals
logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt; // divsqrt shif amount logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt; // divsqrt shif amount
logic [P.NORMSHIFTSZ-1:0] DivShiftIn; // divsqrt shift input logic [P.NORMSHIFTSZ-1:0] DivShiftIn; // divsqrt shift input

View File

@ -108,7 +108,6 @@ module round import cvw::*; #(parameter cvw_t P) (
// 11 - do nothing if a small number was supposed to subtracted (the sticky bit was set by the small number) // 11 - do nothing if a small number was supposed to subtracted (the sticky bit was set by the small number)
// - Plus 1 otherwise // - Plus 1 otherwise
// determine what format the final result is in: int or fp // determine what format the final result is in: int or fp
assign IntRes = ToInt; assign IntRes = ToInt;
assign FpRes = ~IntRes; assign FpRes = ~IntRes;
@ -179,15 +178,10 @@ module round import cvw::*; #(parameter cvw_t P) (
end end
// only add the Addend sticky if doing an FMA opperation // only add the Addend sticky if doing an FMA opperation
// - the shifter shifts too far left when there's an underflow (shifting out all possible sticky bits) // - the shifter shifts too far left when there's an underflow (shifting out all possible sticky bits)
assign Sticky = FmaASticky&FmaOp | NormSticky | CvtResUf&CvtOp | FmaMe[P.NE+1]&FmaOp | DivSticky&DivOp; assign Sticky = FmaASticky&FmaOp | NormSticky | CvtResUf&CvtOp | FmaMe[P.NE+1]&FmaOp | DivSticky&DivOp;
// determine round and LSB of the rounded value // determine round and LSB of the rounded value
// - underflow round bit is used to determint the underflow flag // - underflow round bit is used to determint the underflow flag
if (P.FPSIZES == 1) begin if (P.FPSIZES == 1) begin
@ -254,7 +248,6 @@ module round import cvw::*; #(parameter cvw_t P) (
assign LsbRes = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN] : FpLsbRes; assign LsbRes = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN] : FpLsbRes;
assign Round = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN-2] : FpRound; assign Round = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN-2] : FpRound;
always_comb begin always_comb begin
// Determine if you add 1 // Determine if you add 1
case (Frm) case (Frm)
@ -282,9 +275,6 @@ module round import cvw::*; #(parameter cvw_t P) (
assign FpPlus1 = Plus1&~(ToInt&CvtOp); assign FpPlus1 = Plus1&~(ToInt&CvtOp);
assign UfPlus1 = UfCalcPlus1 & (Sticky|Round); assign UfPlus1 = UfCalcPlus1 & (Sticky|Round);
// place Plus1 into the proper position for the format // place Plus1 into the proper position for the format
if (P.FPSIZES == 1) begin if (P.FPSIZES == 1) begin
assign RoundAdd = {{P.FLEN{1'b0}}, FpPlus1}; assign RoundAdd = {{P.FLEN{1'b0}}, FpPlus1};
@ -302,13 +292,9 @@ module round import cvw::*; #(parameter cvw_t P) (
end else if (P.FPSIZES == 4) end else if (P.FPSIZES == 4)
assign RoundAdd = {(P.Q_NE+1+P.H_NF)'(0), FpPlus1&(OutFmt==P.H_FMT), (P.S_NF-P.H_NF-1)'(0), FpPlus1&(OutFmt==P.S_FMT), (P.D_NF-P.S_NF-1)'(0), FpPlus1&(OutFmt==P.D_FMT), (P.Q_NF-P.D_NF-1)'(0), FpPlus1&(OutFmt==P.Q_FMT)}; assign RoundAdd = {(P.Q_NE+1+P.H_NF)'(0), FpPlus1&(OutFmt==P.H_FMT), (P.S_NF-P.H_NF-1)'(0), FpPlus1&(OutFmt==P.S_FMT), (P.D_NF-P.S_NF-1)'(0), FpPlus1&(OutFmt==P.D_FMT), (P.Q_NF-P.D_NF-1)'(0), FpPlus1&(OutFmt==P.Q_FMT)};
// trim unneeded bits from fraction // trim unneeded bits from fraction
assign RoundFrac = Mf[P.CORRSHIFTSZ-1:P.CORRSHIFTSZ-P.NF]; assign RoundFrac = Mf[P.CORRSHIFTSZ-1:P.CORRSHIFTSZ-P.NF];
// select the exponent // select the exponent
always_comb always_comb
case(PostProcSel) case(PostProcSel)
@ -326,5 +312,4 @@ module round import cvw::*; #(parameter cvw_t P) (
assign {FullRe, Rf} = {Me, RoundFrac} + RoundAdd; assign {FullRe, Rf} = {Me, RoundFrac} + RoundAdd;
assign Re = FullRe[P.NE-1:0]; assign Re = FullRe[P.NE-1:0];
endmodule endmodule

View File

@ -58,7 +58,7 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
input logic CvtResUf, // does the convert result underflow input logic CvtResUf, // does the convert result underflow
input logic [P.XLEN+1:0] CvtNegRes, // the possibly negated of the integer result input logic [P.XLEN+1:0] CvtNegRes, // the possibly negated of the integer result
// outputs // outputs
output logic [P.FLEN-1:0] PostProcRes,// final result output logic [P.FLEN-1:0] PostProcRes, // final result
output logic [P.XLEN-1:0] FCvtIntRes // final integer result output logic [P.XLEN-1:0] FCvtIntRes // final integer result
); );
@ -290,7 +290,6 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
if(Xs&~NaNIn) OfIntRes = {P.XLEN{1'b0}}; // unsigned negitive if(Xs&~NaNIn) OfIntRes = {P.XLEN{1'b0}}; // unsigned negitive
else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive
// select the integer output // select the integer output
// - if the input is invalid (out of bounds NaN or Inf) then output overflow res // - if the input is invalid (out of bounds NaN or Inf) then output overflow res
// - if the input underflows // - if the input underflows

View File

@ -73,6 +73,15 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
logic [`C-1:0][7:1] threshMask; logic [`C-1:0][7:1] threshMask;
logic [P.PLIC_NUM_SRC-1:0] One; logic [P.PLIC_NUM_SRC-1:0] One;
// hacks to handle gracefully PLIC_NUM_SRC being smaller than 32
// Otherwise Questa and other simulators produce part-select out of bounds even
// though sources >=32 are never used
localparam PLIC_SRC_TOP = (P.PLIC_NUM_SRC >= 32) ? P.PLIC_NUM_SRC : 1;
localparam PLIC_SRC_BOT = (P.PLIC_NUM_SRC >= 32) ? 32 : 1;
localparam PLIC_SRC_DINTOP = (P.PLIC_NUM_SRC >= 32) ? P.PLIC_NUM_SRC -32 : 0;
localparam PLIC_SRC_EXT = (P.PLIC_NUM_SRC >= 32) ? 63-P.PLIC_NUM_SRC : 31;
// ======= // =======
// AHB I/O // AHB I/O
// ======= // =======
@ -112,13 +121,8 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
24'h0000??: intPriority[entry[7:2]] <= #1 Din[2:0]; 24'h0000??: intPriority[entry[7:2]] <= #1 Din[2:0];
24'h002000: intEn[0][PLIC_NUM_SRC_MIN_32:1] <= #1 Din[PLIC_NUM_SRC_MIN_32:1]; 24'h002000: intEn[0][PLIC_NUM_SRC_MIN_32:1] <= #1 Din[PLIC_NUM_SRC_MIN_32:1];
24'h002080: intEn[1][PLIC_NUM_SRC_MIN_32:1] <= #1 Din[PLIC_NUM_SRC_MIN_32:1]; 24'h002080: intEn[1][PLIC_NUM_SRC_MIN_32:1] <= #1 Din[PLIC_NUM_SRC_MIN_32:1];
24'h002004: if (P.PLIC_NUM_SRC >= 32) intEn[0][PLIC_SRC_TOP:PLIC_SRC_BOT] <= #1 Din[PLIC_SRC_DINTOP:0];
// verilator lint_off SELRANGE 24'h002084: if (P.PLIC_NUM_SRC >= 32) intEn[1][PLIC_SRC_TOP:PLIC_SRC_BOT] <= #1 Din[PLIC_SRC_DINTOP:0];
// *** RT: Long term we want to factor out these variable number of registers as a generate loop
// I think this won't work as a case statement.
24'h002004: if (P.PLIC_NUM_SRC >= 32) intEn[0][P.PLIC_NUM_SRC:32] <= #1 Din[P.PLIC_NUM_SRC-32:0];
24'h002084: if (P.PLIC_NUM_SRC >= 32) intEn[1][P.PLIC_NUM_SRC:32] <= #1 Din[P.PLIC_NUM_SRC-32:0];
// verilator lint_on SELRANGE
24'h200000: intThreshold[0] <= #1 Din[2:0]; 24'h200000: intThreshold[0] <= #1 Din[2:0];
24'h200004: intInProgress <= #1 intInProgress & ~(One << (Din[5:0]-1)); // lower "InProgress" to signify completion 24'h200004: intInProgress <= #1 intInProgress & ~(One << (Din[5:0]-1)); // lower "InProgress" to signify completion
24'h201000: intThreshold[1] <= #1 Din[2:0]; 24'h201000: intThreshold[1] <= #1 Din[2:0];
@ -131,20 +135,10 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
24'h0000??: Dout <= #1 {29'b0,intPriority[entry[7:2]]}; 24'h0000??: Dout <= #1 {29'b0,intPriority[entry[7:2]]};
24'h001000: Dout <= #1 {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intPending[PLIC_NUM_SRC_MIN_32:1],1'b0}; 24'h001000: Dout <= #1 {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intPending[PLIC_NUM_SRC_MIN_32:1],1'b0};
24'h002000: Dout <= #1 {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intEn[0][PLIC_NUM_SRC_MIN_32:1],1'b0}; 24'h002000: Dout <= #1 {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intEn[0][PLIC_NUM_SRC_MIN_32:1],1'b0};
24'h001004: if (P.PLIC_NUM_SRC >= 32) Dout <= #1 {{(PLIC_SRC_EXT){1'b0}},intPending[PLIC_SRC_TOP:PLIC_SRC_BOT]};
// verilator lint_off SELRANGE 24'h002004: if (P.PLIC_NUM_SRC >= 32) Dout <= #1 {{(PLIC_SRC_EXT){1'b0}},intEn[0][PLIC_SRC_TOP:PLIC_SRC_BOT]};
// verilator lint_off WIDTHTRUNC
24'h001004: if (P.PLIC_NUM_SRC >= 32) Dout <= #1 {{(63-P.PLIC_NUM_SRC){1'b0}},intPending[P.PLIC_NUM_SRC:32]};
24'h002004: if (P.PLIC_NUM_SRC >= 32) Dout <= #1 {{(63-P.PLIC_NUM_SRC){1'b0}},intEn[0][P.PLIC_NUM_SRC:32]};
// verilator lint_on SELRANGE
// verilator lint_on WIDTHTRUNC
24'h002080: Dout <= #1 {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intEn[1][PLIC_NUM_SRC_MIN_32:1],1'b0}; 24'h002080: Dout <= #1 {{(31-PLIC_NUM_SRC_MIN_32){1'b0}},intEn[1][PLIC_NUM_SRC_MIN_32:1],1'b0};
// verilator lint_off SELRANGE 24'h002084: if (P.PLIC_NUM_SRC >= 32) Dout <= #1 {{(PLIC_SRC_EXT){1'b0}},intEn[1][PLIC_SRC_TOP:PLIC_SRC_BOT]};
// verilator lint_off WIDTHTRUNC
24'h002084: if (P.PLIC_NUM_SRC >= 32) Dout <= #1 {{(63-P.PLIC_NUM_SRC){1'b0}},intEn[1][P.PLIC_NUM_SRC:32]};
// verilator lint_on SELRANGE
// verilator lint_on WIDTHTRUNC
24'h200000: Dout <= #1 {29'b0,intThreshold[0]}; 24'h200000: Dout <= #1 {29'b0,intThreshold[0]};
24'h200004: begin 24'h200004: begin
Dout <= #1 {26'b0,intClaim[0]}; Dout <= #1 {26'b0,intClaim[0]};

View File

@ -27,6 +27,18 @@
#include "WALLY-init-lib.h" #include "WALLY-init-lib.h"
main: main:
# Tests sret in machine mode
la t1, sretdone
csrw sepc, t1
sret
sretdone:
addi t2, x0, 42
# switch to user mode
li a0, 0
ecall
sret #should be treated as illegal instruction
mret #mret in user mode and should be illegal
# switch to supervisor mode # switch to supervisor mode
li a0, 1 li a0, 1
@ -44,16 +56,38 @@ main:
csrw satp, zero csrw satp, zero
# STIMECMP from S mode # STIMECMP from S mode
li t0, 1 # 1st is when MENVCFG_STCE is cleared
li a0, 3
ecall # starts in M-mode
csrw menvcfg, x0
li a0, 1
ecall # enter S-mode ecall # enter S-mode
csrw stimecmp, zero csrw stimecmp, zero
li t0, 3 li a0, 3
ecall # return to M-mode ecall # return to M-mode
csrsi mcounteren, 2 # mcounteren_tm = 1 csrsi mcounteren, 2 # mcounteren_tm = 1
li t0, 1 li a0, 1
ecall # supervisor mode again ecall # supervisor mode again
csrw stimecmp, zero csrw stimecmp, zero
li t0, 3 li a0, 3
ecall # machine mode again
# STIMECMP from S mode
# 2nd is when MENVCFG_STCE is set
csrci mcounteren, 2 # mcounteren_tm = 0
li t0, 1
slli t0, t0, 63
csrw menvcfg, t0
li a0, 1
ecall # enter S-mode
csrw stimecmp, zero
li a0, 3
ecall # return to M-mode
csrsi mcounteren, 2 # mcounteren_tm = 1
li a0, 1
ecall # supervisor mode again
csrw stimecmp, zero
li a0, 3
ecall # machine mode again ecall # machine mode again