forked from Github_Repos/cvw
Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main
This commit is contained in:
commit
0c52c7f69c
@ -41,23 +41,24 @@ module fctrl (
|
||||
input logic [2:0] FRM_REGW, // rounding mode from CSR
|
||||
input logic [1:0] STATUS_FS, // is FPU enabled?
|
||||
input logic FDivBusyE, // is the divider busy
|
||||
output logic IllegalFPUInstrD, IllegalFPUInstrM, // Is the instruction an illegal fpu instruction
|
||||
output logic IllegalFPUInstrM, // Is the instruction an illegal fpu instruction
|
||||
output logic FRegWriteM, FRegWriteW, // FP register write enable
|
||||
output logic [2:0] FrmM, // FP rounding mode
|
||||
output logic [`FMTBITS-1:0] FmtE, FmtM, // FP format
|
||||
output logic DivStartE, // Start division or squareroot
|
||||
output logic XEnE, YEnE, ZEnE,
|
||||
output logic YEnForwardE, ZEnForwardE,
|
||||
output logic FWriteIntE, FWriteIntM, // Write to integer register
|
||||
output logic FWriteIntE, FCvtIntE, FWriteIntM, // Write to integer register
|
||||
output logic [2:0] OpCtrlE, OpCtrlM, // Select which opperation to do in each component
|
||||
output logic [1:0] FResSelE, FResSelM, FResSelW, // Select one of the results that finish in the memory stage
|
||||
output logic [1:0] PostProcSelE, PostProcSelM, // select result in the post processing unit
|
||||
output logic FCvtIntW,
|
||||
output logic [4:0] Adr1E, Adr2E, Adr3E // adresses of each input
|
||||
);
|
||||
|
||||
`define FCTRLW 11
|
||||
logic [`FCTRLW-1:0] ControlsD;
|
||||
logic IllegalFPUInstrE;
|
||||
logic IllegalFPUInstrD, IllegalFPUInstrE;
|
||||
logic FRegWriteD; // FP register write enable
|
||||
logic DivStartD; // integer register write enable
|
||||
logic FWriteIntD; // integer register write enable
|
||||
@ -67,22 +68,40 @@ module fctrl (
|
||||
logic [1:0] FResSelD; // Select one of the results that finish in the memory stage
|
||||
logic [2:0] FrmD, FrmE; // FP rounding mode
|
||||
logic [`FMTBITS-1:0] FmtD; // FP format
|
||||
//*** will putting x for don't cares reduce area in synthisis???
|
||||
logic [1:0] Fmt;
|
||||
logic SupportedFmt;
|
||||
|
||||
// FPU Instruction Decoder
|
||||
assign Fmt = Funct7D[1:0];
|
||||
// Note: only Fmt is checked; fcvt does not check destination format
|
||||
assign SupportedFmt = (Fmt == 2'b00 | (Fmt == 2'b01 & `D_SUPPORTED) |
|
||||
(Fmt == 2'b10 & `ZFH_SUPPORTED) | (Fmt == 2'b11 & `Q_SUPPORTED));
|
||||
always_comb
|
||||
if (STATUS_FS == 2'b00) // FPU instructions are illegal when FPU is disabled
|
||||
ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1;
|
||||
else if (OpD != 7'b0000111 & OpD != 7'b0100111 & ~SupportedFmt)
|
||||
ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1; // for anything other than loads and stores, check for supported format
|
||||
else case(OpD)
|
||||
// FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr
|
||||
7'b0000111: case(Funct3D)
|
||||
3'b010: ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0; // flw
|
||||
3'b011: ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0; // fld
|
||||
default: ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1; // non-implemented instruction
|
||||
3'b010: ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0; // flw
|
||||
3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0; // fld
|
||||
else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1; // fld not supported
|
||||
3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0; // flq
|
||||
else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1; // flq not supported
|
||||
3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0; // flh
|
||||
else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1; // flh not supported
|
||||
default: ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1; // non-implemented instruction
|
||||
endcase
|
||||
7'b0100111: case(Funct3D)
|
||||
3'b010: ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0; // fsw
|
||||
3'b011: ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0; // fsd
|
||||
default: ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1; // non-implemented instruction
|
||||
3'b010: ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0; // fsw
|
||||
3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0; // fsd
|
||||
else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1; // fsd not supported
|
||||
3'b100: if (`Q_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0; // fsq
|
||||
else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1; // fsq not supported
|
||||
3'b001: if (`ZFH_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0; // fsh
|
||||
else ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1; // fsh not supported
|
||||
default: ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1; // non-implemented instruction
|
||||
endcase
|
||||
7'b1000011: ControlsD = `FCTRLW'b1_0_01_10_000_0_0; // fmadd
|
||||
7'b1000111: ControlsD = `FCTRLW'b1_0_01_10_001_0_0; // fmsub
|
||||
@ -239,23 +258,23 @@ module fctrl (
|
||||
// 10 - xor sign
|
||||
|
||||
// D/E pipleine register
|
||||
flopenrc #(12+`FMTBITS) DECtrlReg3(clk, reset, FlushE, ~StallE,
|
||||
{FRegWriteD, PostProcSelD, FResSelD, FrmD, FmtD, OpCtrlD, FWriteIntD},
|
||||
{FRegWriteE, PostProcSelE, FResSelE, FrmE, FmtE, OpCtrlE, FWriteIntE});
|
||||
flopenrc #(15) DEAdrReg(clk, reset, FlushE, ~StallE, {InstrD[19:15], InstrD[24:20], InstrD[31:27]},
|
||||
flopenrc #(13+`FMTBITS) DECtrlReg3(clk, reset, FlushE, ~StallE,
|
||||
{FRegWriteD, PostProcSelD, FResSelD, FrmD, FmtD, OpCtrlD, FWriteIntD, IllegalFPUInstrD},
|
||||
{FRegWriteE, PostProcSelE, FResSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, IllegalFPUInstrE});
|
||||
flopenrc #(15) DEAdrReg(clk, reset, FlushE, ~StallE, {InstrD[19:15], InstrD[24:20], InstrD[31:27]},
|
||||
{Adr1E, Adr2E, Adr3E});
|
||||
flopenrc #(1) DEDivStartReg(clk, reset, FlushE, ~StallE|FDivBusyE, DivStartD, DivStartE);
|
||||
if(`FLEN>`XLEN)
|
||||
flopenrc #(1) DEIllegalReg(clk, reset, FlushE, ~StallE, IllegalFPUInstrD, IllegalFPUInstrE);
|
||||
assign FCvtIntE = (FResSelE == 2'b01);
|
||||
|
||||
// E/M pipleine register
|
||||
flopenrc #(12+int'(`FMTBITS)) EMCtrlReg (clk, reset, FlushM, ~StallM,
|
||||
{FRegWriteE, FResSelE, PostProcSelE, FrmE, FmtE, OpCtrlE, FWriteIntE},
|
||||
{FRegWriteM, FResSelM, PostProcSelM, FrmM, FmtM, OpCtrlM, FWriteIntM});
|
||||
if(`FLEN>`XLEN)
|
||||
flopenrc #(1) EMIllegalReg(clk, reset, FlushM, ~StallM, IllegalFPUInstrE, IllegalFPUInstrM);
|
||||
flopenrc #(13+int'(`FMTBITS)) EMCtrlReg (clk, reset, FlushM, ~StallM,
|
||||
{FRegWriteE, FResSelE, PostProcSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, IllegalFPUInstrE},
|
||||
{FRegWriteM, FResSelM, PostProcSelM, FrmM, FmtM, OpCtrlM, FWriteIntM, IllegalFPUInstrM});
|
||||
// M/W pipleine register
|
||||
flopenrc #(3) MWCtrlReg(clk, reset, FlushW, ~StallW,
|
||||
{FRegWriteM, FResSelM},
|
||||
{FRegWriteW, FResSelW});
|
||||
|
||||
assign FCvtIntW = (FResSelW == 2'b01);
|
||||
|
||||
endmodule
|
||||
|
@ -50,7 +50,7 @@ module flags(
|
||||
input logic [`NE+1:0] Me, // exponent of the normalized sum
|
||||
input logic [1:0] CvtNegResMsbs, // the negitive integer result's most significant bits
|
||||
input logic FmaAs, FmaPs, // the product and modified Z signs
|
||||
input logic R, UfL, S, UfPlus1, // bits used to determine rounding
|
||||
input logic R, G, S, UfPlus1, // bits used to determine rounding
|
||||
output logic DivByZero,
|
||||
output logic IntInvalid, Invalid, Overflow, // flags used to select the res
|
||||
output logic [4:0] PostProcFlg // flags
|
||||
@ -126,16 +126,16 @@ module flags(
|
||||
// | | | | and if the result is not exact
|
||||
// | | | | | and if the input isnt infinity or NaN
|
||||
// | | | | | |
|
||||
assign Underflow = ((FullRe[`NE+1] | (FullRe == 0) | ((FullRe == 1) & (Me == 0) & ~(UfPlus1&UfL)))&(R|S))&~(InfIn|NaNIn|DivByZero|Invalid);
|
||||
assign Underflow = ((FullRe[`NE+1] | (FullRe == 0) | ((FullRe == 1) & (Me == 0) & ~(UfPlus1&G)))&(R|S|G))&~(InfIn|NaNIn|DivByZero|Invalid);
|
||||
|
||||
// Set Inexact flag if the res is diffrent from what would be outputed given infinite precision
|
||||
// - Don't set the underflow flag if an underflowed res isn't outputed
|
||||
assign FpInexact = (S|Overflow|R)&~(InfIn|NaNIn|DivByZero|Invalid);
|
||||
assign FpInexact = (S|G|Overflow|R)&~(InfIn|NaNIn|DivByZero|Invalid);
|
||||
|
||||
// if the res is too small to be represented and not 0
|
||||
// | and if the res is not invalid (outside the integer bounds)
|
||||
// | |
|
||||
assign IntInexact = ((CvtCe[`NE]&~XZero)|S|R)&~IntInvalid;
|
||||
assign IntInexact = ((CvtCe[`NE]&~XZero)|S|R|G)&~IntInvalid;
|
||||
|
||||
// select the inexact flag to output
|
||||
assign Inexact = ToInt ? IntInexact : FpInexact;
|
||||
|
@ -44,12 +44,13 @@ module fpu (
|
||||
output logic FpLoadStoreM, // Fp load instruction? (to LSU)
|
||||
output logic FStallD, // Stall the decode stage (To HZU)
|
||||
output logic FWriteIntE, // integer register write enable (to IEU)
|
||||
output logic FCvtIntE, // Convert to int (to IEU)
|
||||
output logic [`FLEN-1:0] FWriteDataM, // Data to be written to memory (to LSU)
|
||||
output logic [`XLEN-1:0] FIntResM, // data to be written to integer register (to IEU)
|
||||
output logic [`XLEN-1:0] FCvtIntResW, // convert result to to be written to integer register (to IEU)
|
||||
output logic [1:0] FResSelW, // final result selection (to IEU)
|
||||
output logic FCvtIntW, // select FCvtIntRes (to IEU)
|
||||
output logic FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage) (to HZU)
|
||||
output logic IllegalFPUInstrD, // Is the instruction an illegal fpu instruction (to privileged unit)
|
||||
output logic IllegalFPUInstrM, // Is the instruction an illegal fpu instruction (to privileged unit)
|
||||
output logic [4:0] SetFflagsM // FPU flags (to privileged unit)
|
||||
);
|
||||
|
||||
@ -67,10 +68,9 @@ module fpu (
|
||||
logic FWriteIntM; // Write to integer register
|
||||
logic [1:0] ForwardXE, ForwardYE, ForwardZE; // forwarding mux control signals
|
||||
logic [2:0] OpCtrlE, OpCtrlM; // Select which opperation to do in each component
|
||||
logic [1:0] FResSelE, FResSelM; // Select one of the results that finish in the memory stage
|
||||
logic [1:0] FResSelE, FResSelM, FResSelW; // Select one of the results that finish in the memory stage
|
||||
logic [1:0] PostProcSelE, PostProcSelM; // select result in the post processing unit
|
||||
logic [4:0] Adr1E, Adr2E, Adr3E; // adresses of each input
|
||||
logic IllegalFPUInstrM;
|
||||
logic XEnE, YEnE, ZEnE;
|
||||
logic YEnForwardE, ZEnForwardE;
|
||||
|
||||
@ -147,7 +147,7 @@ module fpu (
|
||||
logic [`FLEN-1:0] AlignedSrcAE; // align SrcA to the floating point format
|
||||
logic [`FLEN-1:0] BoxedZeroE; // Zero value for Z for multiplication, with NaN boxing if needed
|
||||
logic [`FLEN-1:0] BoxedOneE; // Zero value for Z for multiplication, with NaN boxing if needed
|
||||
|
||||
|
||||
// DECODE STAGE
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -163,9 +163,9 @@ module fpu (
|
||||
// calculate FP control signals
|
||||
fctrl fctrl (.Funct7D(InstrD[31:25]), .OpD(InstrD[6:0]), .Rs2D(InstrD[24:20]), .Funct3D(InstrD[14:12]), .InstrD,
|
||||
.StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW, .FRM_REGW, .STATUS_FS, .FDivBusyE,
|
||||
.reset, .clk, .IllegalFPUInstrD, .FRegWriteM, .FRegWriteW, .FrmM, .FmtE, .FmtM, .YEnForwardE, .ZEnForwardE,
|
||||
.DivStartE, .FWriteIntE, .FWriteIntM, .OpCtrlE, .OpCtrlM, .IllegalFPUInstrM, .XEnE, .YEnE, .ZEnE,
|
||||
.FResSelE, .FResSelM, .FResSelW, .PostProcSelE, .PostProcSelM, .Adr1E, .Adr2E, .Adr3E);
|
||||
.reset, .clk, .FRegWriteM, .FRegWriteW, .FrmM, .FmtE, .FmtM, .YEnForwardE, .ZEnForwardE,
|
||||
.DivStartE, .FWriteIntE, .FCvtIntE, .FWriteIntM, .OpCtrlE, .OpCtrlM, .IllegalFPUInstrM, .XEnE, .YEnE, .ZEnE,
|
||||
.FResSelE, .FResSelM, .FResSelW, .PostProcSelE, .PostProcSelM, .FCvtIntW, .Adr1E, .Adr2E, .Adr3E);
|
||||
|
||||
// FP register file
|
||||
fregfile fregfile (.clk, .reset, .we4(FRegWriteW),
|
||||
|
@ -83,15 +83,13 @@ module postprocess (
|
||||
logic [`NE+1:0] Me;
|
||||
logic [`CORRSHIFTSZ-1:0] Mf; // corectly shifted fraction
|
||||
logic [`NE+1:0] FullRe; // Re with bits to determine sign and overflow
|
||||
logic S; // S bit
|
||||
logic UfPlus1; // do you add one (for determining underflow flag)
|
||||
logic R; // bits needed to determine rounding
|
||||
logic [$clog2(`NORMSHIFTSZ)-1:0] ShiftAmt; // normalization shift count
|
||||
logic [`NORMSHIFTSZ-1:0] ShiftIn; // is the sum zero
|
||||
logic [`NORMSHIFTSZ-1:0] Shifted; // the shifted result
|
||||
logic Plus1; // add one to the final result?
|
||||
logic IntInvalid, Overflow, Invalid; // flags
|
||||
logic UfL;
|
||||
logic G, R, S; // bits needed to determine rounding
|
||||
logic [`FMTBITS-1:0] OutFmt;
|
||||
// fma signals
|
||||
logic [`NE+1:0] FmaMe; // exponent of the normalized sum
|
||||
@ -201,16 +199,16 @@ module postprocess (
|
||||
roundsign roundsign(.FmaPs, .FmaAs, .FmaInvA, .FmaOp, .DivOp, .CvtOp, .FmaNegSum,
|
||||
.Sqrt, .FmaSs, .Xs, .Ys, .CvtCs, .Ms);
|
||||
|
||||
round round(.OutFmt, .Frm, .S, .FmaZmS, .Plus1, .PostProcSel, .CvtCe, .Qe,
|
||||
round round(.OutFmt, .Frm, .FmaZmS, .Plus1, .PostProcSel, .CvtCe, .Qe,
|
||||
.Ms, .FmaMe, .FmaOp, .CvtOp, .CvtResDenormUf, .Mf, .ToInt, .CvtResUf,
|
||||
.DivS, .DivDone,
|
||||
.DivOp, .UfPlus1, .FullRe, .Rf, .Re, .R, .UfL, .Me);
|
||||
.DivOp, .UfPlus1, .FullRe, .Rf, .Re, .S, .R, .G, .Me);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Sign calculation
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
resultsign resultsign(.Frm, .FmaPs, .FmaAs, .FmaMe, .R, .S,
|
||||
resultsign resultsign(.Frm, .FmaPs, .FmaAs, .FmaMe, .R, .S, .G,
|
||||
.FmaOp, .ZInf, .InfIn, .FmaSZero, .Mult, .Ms, .Ws);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -220,7 +218,7 @@ module postprocess (
|
||||
flags flags(.XSNaN, .YSNaN, .ZSNaN, .XInf, .YInf, .ZInf, .InfIn, .XZero, .YZero,
|
||||
.Xs, .Sqrt, .ToInt, .IntToFp, .Int64, .Signed, .OutFmt, .CvtCe,
|
||||
.NaNIn, .FmaAs, .FmaPs, .R, .IntInvalid, .DivByZero,
|
||||
.UfL, .S, .UfPlus1, .CvtOp, .DivOp, .FmaOp, .FullRe, .Plus1,
|
||||
.G, .S, .UfPlus1, .CvtOp, .DivOp, .FmaOp, .FullRe, .Plus1,
|
||||
.Me, .CvtNegResMsbs, .Invalid, .Overflow, .PostProcFlg);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -39,6 +39,7 @@ module resultsign(
|
||||
input logic Mult,
|
||||
input logic R,
|
||||
input logic S,
|
||||
input logic G,
|
||||
input logic Ms,
|
||||
output logic Ws
|
||||
);
|
||||
@ -60,7 +61,7 @@ module resultsign(
|
||||
// - if a multiply opperation is done, then use the products sign(Ps)
|
||||
// - if the zero sum is not exactly zero i.e. R|S use the sign of the exact result (which is the product's sign)
|
||||
// - if an effective addition occurs (P+A or -P+-A or P--A) then use the product's sign
|
||||
assign Zeros = (FmaPs^FmaAs)&~(R|S)&~Mult ? Frm[1:0] == 2'b10 : FmaPs;
|
||||
assign Zeros = (FmaPs^FmaAs)&~(R|G|S)&~Mult ? Frm[1:0] == 2'b10 : FmaPs;
|
||||
|
||||
|
||||
// is the result negitive
|
||||
|
@ -60,16 +60,14 @@ module round(
|
||||
output logic S, // sticky bit
|
||||
output logic [`NE+1:0] Me,
|
||||
output logic Plus1,
|
||||
output logic R, UfL // bits needed to calculate rounding
|
||||
output logic R, G // bits needed to calculate rounding
|
||||
);
|
||||
logic L; // bit used for rounding - least significant bit of the normalized sum
|
||||
logic UfCalcPlus1;
|
||||
logic NormS; // normalized sum's sticky bit
|
||||
logic UfS; // sticky bit for underlow calculation
|
||||
logic [`NF-1:0] RoundFrac;
|
||||
logic FpRes, IntRes;
|
||||
logic UfR;
|
||||
logic FpRound, FpLSBRes, FpUfRound;
|
||||
logic FpG, FpL, FpR;
|
||||
logic L; // lsb of result
|
||||
logic CalcPlus1, FpPlus1;
|
||||
logic [`FLEN:0] RoundAdd; // how much to add to the result
|
||||
|
||||
@ -176,106 +174,101 @@ module round(
|
||||
|
||||
// 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)
|
||||
assign UfS = FmaZmS&FmaOp | NormS | CvtResUf&CvtOp | FmaMe[`NE+1]&FmaOp | DivS&DivOp;
|
||||
assign S = FmaZmS&FmaOp | NormS | CvtResUf&CvtOp | FmaMe[`NE+1]&FmaOp | DivS&DivOp;
|
||||
|
||||
// determine round and LSB of the rounded value
|
||||
// - underflow round bit is used to determint the underflow flag
|
||||
if (`FPSIZES == 1) begin
|
||||
assign FpRound = Mf[`CORRSHIFTSZ-`NF-1];
|
||||
assign FpLSBRes = Mf[`CORRSHIFTSZ-`NF];
|
||||
assign FpUfRound = Mf[`CORRSHIFTSZ-`NF-2];
|
||||
assign FpG = Mf[`CORRSHIFTSZ-`NF-1];
|
||||
assign FpL = Mf[`CORRSHIFTSZ-`NF];
|
||||
assign FpR = Mf[`CORRSHIFTSZ-`NF-2];
|
||||
|
||||
end else if (`FPSIZES == 2) begin
|
||||
assign FpRound = OutFmt ? Mf[`CORRSHIFTSZ-`NF-1] : Mf[`CORRSHIFTSZ-`NF1-1];
|
||||
assign FpLSBRes = OutFmt ? Mf[`CORRSHIFTSZ-`NF] : Mf[`CORRSHIFTSZ-`NF1];
|
||||
assign FpUfRound = OutFmt ? Mf[`CORRSHIFTSZ-`NF-2] : Mf[`CORRSHIFTSZ-`NF1-2];
|
||||
assign FpG = OutFmt ? Mf[`CORRSHIFTSZ-`NF-1] : Mf[`CORRSHIFTSZ-`NF1-1];
|
||||
assign FpL = OutFmt ? Mf[`CORRSHIFTSZ-`NF] : Mf[`CORRSHIFTSZ-`NF1];
|
||||
assign FpR = OutFmt ? Mf[`CORRSHIFTSZ-`NF-2] : Mf[`CORRSHIFTSZ-`NF1-2];
|
||||
|
||||
end else if (`FPSIZES == 3) begin
|
||||
always_comb
|
||||
case (OutFmt)
|
||||
`FMT: begin
|
||||
FpRound = Mf[`CORRSHIFTSZ-`NF-1];
|
||||
FpLSBRes = Mf[`CORRSHIFTSZ-`NF];
|
||||
FpUfRound = Mf[`CORRSHIFTSZ-`NF-2];
|
||||
FpG = Mf[`CORRSHIFTSZ-`NF-1];
|
||||
FpL = Mf[`CORRSHIFTSZ-`NF];
|
||||
FpR = Mf[`CORRSHIFTSZ-`NF-2];
|
||||
end
|
||||
`FMT1: begin
|
||||
FpRound = Mf[`CORRSHIFTSZ-`NF1-1];
|
||||
FpLSBRes = Mf[`CORRSHIFTSZ-`NF1];
|
||||
FpUfRound = Mf[`CORRSHIFTSZ-`NF1-2];
|
||||
FpG = Mf[`CORRSHIFTSZ-`NF1-1];
|
||||
FpL = Mf[`CORRSHIFTSZ-`NF1];
|
||||
FpR = Mf[`CORRSHIFTSZ-`NF1-2];
|
||||
end
|
||||
`FMT2: begin
|
||||
FpRound = Mf[`CORRSHIFTSZ-`NF2-1];
|
||||
FpLSBRes = Mf[`CORRSHIFTSZ-`NF2];
|
||||
FpUfRound = Mf[`CORRSHIFTSZ-`NF2-2];
|
||||
FpG = Mf[`CORRSHIFTSZ-`NF2-1];
|
||||
FpL = Mf[`CORRSHIFTSZ-`NF2];
|
||||
FpR = Mf[`CORRSHIFTSZ-`NF2-2];
|
||||
end
|
||||
default: begin
|
||||
FpRound = 1'bx;
|
||||
FpLSBRes = 1'bx;
|
||||
FpUfRound = 1'bx;
|
||||
FpG = 1'bx;
|
||||
FpL = 1'bx;
|
||||
FpR = 1'bx;
|
||||
end
|
||||
endcase
|
||||
end else if (`FPSIZES == 4) begin
|
||||
always_comb
|
||||
case (OutFmt)
|
||||
2'h3: begin
|
||||
FpRound = Mf[`CORRSHIFTSZ-`Q_NF-1];
|
||||
FpLSBRes = Mf[`CORRSHIFTSZ-`Q_NF];
|
||||
FpUfRound = Mf[`CORRSHIFTSZ-`Q_NF-2];
|
||||
FpG = Mf[`CORRSHIFTSZ-`Q_NF-1];
|
||||
FpL = Mf[`CORRSHIFTSZ-`Q_NF];
|
||||
FpR = Mf[`CORRSHIFTSZ-`Q_NF-2];
|
||||
end
|
||||
2'h1: begin
|
||||
FpRound = Mf[`CORRSHIFTSZ-`D_NF-1];
|
||||
FpLSBRes = Mf[`CORRSHIFTSZ-`D_NF];
|
||||
FpUfRound = Mf[`CORRSHIFTSZ-`D_NF-2];
|
||||
FpG = Mf[`CORRSHIFTSZ-`D_NF-1];
|
||||
FpL = Mf[`CORRSHIFTSZ-`D_NF];
|
||||
FpR = Mf[`CORRSHIFTSZ-`D_NF-2];
|
||||
end
|
||||
2'h0: begin
|
||||
FpRound = Mf[`CORRSHIFTSZ-`S_NF-1];
|
||||
FpLSBRes = Mf[`CORRSHIFTSZ-`S_NF];
|
||||
FpUfRound = Mf[`CORRSHIFTSZ-`S_NF-2];
|
||||
FpG = Mf[`CORRSHIFTSZ-`S_NF-1];
|
||||
FpL = Mf[`CORRSHIFTSZ-`S_NF];
|
||||
FpR = Mf[`CORRSHIFTSZ-`S_NF-2];
|
||||
end
|
||||
2'h2: begin
|
||||
FpRound = Mf[`CORRSHIFTSZ-`H_NF-1];
|
||||
FpLSBRes = Mf[`CORRSHIFTSZ-`H_NF];
|
||||
FpUfRound = Mf[`CORRSHIFTSZ-`H_NF-2];
|
||||
FpG = Mf[`CORRSHIFTSZ-`H_NF-1];
|
||||
FpL = Mf[`CORRSHIFTSZ-`H_NF];
|
||||
FpR = Mf[`CORRSHIFTSZ-`H_NF-2];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
assign R = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN-1] : FpRound;
|
||||
assign L = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN] : FpLSBRes;
|
||||
assign UfR = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN-2] : FpUfRound;
|
||||
|
||||
// used to determine underflow flag
|
||||
assign UfL = FpRound;
|
||||
// determine sticky
|
||||
assign S = UfS | UfR;
|
||||
assign G = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN-1] : FpG;
|
||||
assign L = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN] : FpL;
|
||||
assign R = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN-2] : FpR;
|
||||
|
||||
|
||||
always_comb begin
|
||||
// Determine if you add 1
|
||||
case (Frm)
|
||||
3'b000: CalcPlus1 = R & (S| L);//round to nearest even
|
||||
3'b000: CalcPlus1 = G & (R|S|L);//round to nearest even
|
||||
3'b001: CalcPlus1 = 0;//round to zero
|
||||
3'b010: CalcPlus1 = Ms;//round down
|
||||
3'b011: CalcPlus1 = ~Ms;//round up
|
||||
3'b100: CalcPlus1 = R;//round to nearest max magnitude
|
||||
3'b100: CalcPlus1 = G;//round to nearest max magnitude
|
||||
default: CalcPlus1 = 1'bx;
|
||||
endcase
|
||||
// Determine if you add 1 (for underflow flag)
|
||||
case (Frm)
|
||||
3'b000: UfCalcPlus1 = UfR & (UfS| UfL);//round to nearest even
|
||||
3'b000: UfCalcPlus1 = R & (S|G);//round to nearest even
|
||||
3'b001: UfCalcPlus1 = 0;//round to zero
|
||||
3'b010: UfCalcPlus1 = Ms;//round down
|
||||
3'b011: UfCalcPlus1 = ~Ms;//round up
|
||||
3'b100: UfCalcPlus1 = UfR;//round to nearest max magnitude
|
||||
3'b100: UfCalcPlus1 = R;//round to nearest max magnitude
|
||||
default: UfCalcPlus1 = 1'bx;
|
||||
endcase
|
||||
|
||||
end
|
||||
|
||||
// If an answer is exact don't round
|
||||
assign Plus1 = CalcPlus1 & (S | R);
|
||||
assign Plus1 = CalcPlus1 & (S|R|G);
|
||||
assign FpPlus1 = Plus1&~(ToInt&CvtOp);
|
||||
assign UfPlus1 = UfCalcPlus1 & S; // UfR is part of sticky
|
||||
assign UfPlus1 = UfCalcPlus1 & (S|R);
|
||||
|
||||
// Compute rounded result
|
||||
if (`FPSIZES == 1) begin
|
||||
|
@ -56,7 +56,7 @@ module srtfsm(
|
||||
output logic DivDone,
|
||||
output logic NegSticky,
|
||||
output logic DivBusy
|
||||
);
|
||||
);
|
||||
|
||||
typedef enum logic [1:0] {IDLE, BUSY, DONE} statetype;
|
||||
statetype state;
|
||||
@ -69,15 +69,15 @@ module srtfsm(
|
||||
assign DivBusy = (state == BUSY);
|
||||
// calculate sticky bit
|
||||
// - there is a chance that a value is subtracted infinitly, resulting in an exact QM result
|
||||
// this is only a problem on radix 2 (and pssibly maximally redundant 4) since minimally redundant
|
||||
// this is only a problem on radix 2 (and possibly maximally redundant 4) since minimally redundant
|
||||
// radix-4 division can't create a QM that continually adds 0's
|
||||
if (`RADIX == 2) begin
|
||||
logic [`DIVb+3:0] FZero, FSticky;
|
||||
logic [`DIVb+3:0] LastK, FirstK;
|
||||
assign LastK = ({4'b1111, LastC} & ~({4'b1111, LastC} << 1));
|
||||
assign FirstK = ({4'b1111, FirstC<<1} & ~({4'b1111, FirstC<<1} << 1));
|
||||
assign FZero = SqrtM ? {{2{LastSM[`DIVb]}}, LastSM, 2'b0} | {LastK,1'b0} : {4'b1,D,{`DIVb-`DIVN+2{1'b0}}};
|
||||
assign FSticky = SqrtM ? {FirstSM, 2'b0} | {FirstK,1'b0} : {4'b1,D,{`DIVb-`DIVN+2{1'b0}}};
|
||||
logic [`DIVb+2:0] LastK, FirstK;
|
||||
assign LastK = ({3'b111, LastC} & ~({3'b111, LastC} << 1));
|
||||
assign FirstK = ({3'b111, FirstC<<1} & ~({3'b111, FirstC<<1} << 1));
|
||||
assign FZero = SqrtM ? {LastSM[`DIVb], LastSM, 2'b0} | {LastK,1'b0} : {3'b1,D,{`DIVb-`DIVN+2{1'b0}}};
|
||||
assign FSticky = SqrtM ? {FirstSM[`DIVb], FirstSM, 2'b0} | {FirstK,1'b0} : {3'b1,D,{`DIVb-`DIVN+2{1'b0}}};
|
||||
// *** |... for continual -1 is not efficent fix - also only needed for radix-2
|
||||
assign WZero = ((NextWSN^NextWCN)=={NextWSN[`DIVb+2:0]|NextWCN[`DIVb+2:0], 1'b0})|(((NextWSN+NextWCN+FZero)==0)&qn[`DIVCOPIES-1]);
|
||||
assign DivSE = |W&~((W+FSticky)==0); //***not efficent fix == and need the & qn
|
||||
|
@ -44,7 +44,6 @@ module datapath (
|
||||
input logic ALUResultSrcE,
|
||||
input logic JumpE,
|
||||
input logic BranchSignedE,
|
||||
input logic IllegalFPUInstrE,
|
||||
input logic [`XLEN-1:0] PCE,
|
||||
input logic [`XLEN-1:0] PCLinkE,
|
||||
output logic [1:0] FlagsE,
|
||||
@ -52,7 +51,7 @@ module datapath (
|
||||
output logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
||||
// Memory stage signals
|
||||
input logic StallM, FlushM,
|
||||
input logic FWriteIntM,
|
||||
input logic FWriteIntM, FCvtIntW,
|
||||
input logic [`XLEN-1:0] FIntResM,
|
||||
output logic [`XLEN-1:0] SrcAM,
|
||||
output logic [`XLEN-1:0] WriteDataM,
|
||||
@ -62,7 +61,6 @@ module datapath (
|
||||
input logic SquashSCW,
|
||||
input logic [2:0] ResultSrcW,
|
||||
input logic [`XLEN-1:0] FCvtIntResW,
|
||||
input logic [1:0] FResSelW,
|
||||
input logic [`XLEN-1:0] ReadDataW,
|
||||
// input logic [`XLEN-1:0] PCLinkW,
|
||||
input logic [`XLEN-1:0] CSRReadValW, MDUResultW,
|
||||
@ -87,8 +85,8 @@ module datapath (
|
||||
// Writeback stage signals
|
||||
logic [`XLEN-1:0] SCResultW;
|
||||
logic [`XLEN-1:0] ResultW;
|
||||
logic [`XLEN-1:0] IFResultW;
|
||||
|
||||
logic [`XLEN-1:0] IFResultW, IFCvtResultW;
|
||||
|
||||
// Decode stage
|
||||
assign Rs1D = InstrD[19:15];
|
||||
assign Rs2D = InstrD[24:20];
|
||||
@ -123,16 +121,14 @@ module datapath (
|
||||
flopenrc #(`XLEN) IFResultWReg(clk, reset, FlushW, ~StallW, IFResultM, IFResultW);
|
||||
flopenrc #(5) RdWReg(clk, reset, FlushW, ~StallW, RdM, RdW);
|
||||
|
||||
// floating point interactions: fcvt, fp stores
|
||||
// floating point inputs: FIntResM comes from fclass, fcmp, fmv; FCvtIntResW comes from fcvt
|
||||
if (`F_SUPPORTED) begin:fpmux
|
||||
logic [`XLEN-1:0] IFCvtResultW;
|
||||
mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, IFResultM);
|
||||
mux2 #(`XLEN) cvtresultmuxW(IFResultW, FCvtIntResW, ~FResSelW[1]&FResSelW[0], IFCvtResultW);
|
||||
mux5 #(`XLEN) resultmuxW(IFCvtResultW, ReadDataW, CSRReadValW, MDUResultW, SCResultW, ResultSrcW, ResultW);
|
||||
mux2 #(`XLEN) cvtresultmuxW(IFResultW, FCvtIntResW, FCvtIntW, IFCvtResultW);
|
||||
end else begin:fpmux
|
||||
assign IFResultM = IEUResultM;
|
||||
mux5 #(`XLEN) resultmuxW(IFResultW, ReadDataW, CSRReadValW, MDUResultW, SCResultW, ResultSrcW, ResultW);
|
||||
assign IFResultM = IEUResultM; assign IFCvtResultW = IFResultW;
|
||||
end
|
||||
mux5 #(`XLEN) resultmuxW(IFCvtResultW, ReadDataW, CSRReadValW, MDUResultW, SCResultW, ResultSrcW, ResultW);
|
||||
|
||||
// handle Store Conditional result if atomic extension supported
|
||||
if (`A_SUPPORTED) assign SCResultW = {{(`XLEN-1){1'b0}}, SquashSCW};
|
||||
|
@ -35,7 +35,7 @@ module forward(
|
||||
input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW,
|
||||
input logic MemReadE, MDUE, CSRReadE,
|
||||
input logic RegWriteM, RegWriteW,
|
||||
input logic FWriteIntE,
|
||||
input logic FCvtIntE,
|
||||
input logic SCE,
|
||||
// Forwarding controls
|
||||
output logic [1:0] ForwardAE, ForwardBE,
|
||||
@ -58,7 +58,7 @@ module forward(
|
||||
|
||||
// Stall on dependent operations that finish in Mem Stage and can't bypass in time
|
||||
assign MatchDE = (Rs1D == RdE) | (Rs2D == RdE); // Decode-stage instruction source depends on result from execute stage instruction
|
||||
assign FPUStallD = 0; // FWriteIntE & MatchDE; // FPU to Integer transfers have single-cycle latency
|
||||
assign FPUStallD = FCvtIntE & MatchDE; // FPU to Integer transfers have single-cycle latency except fcvt
|
||||
assign LoadStallD = (MemReadE|SCE) & MatchDE;
|
||||
assign MDUStallD = MDUE & MatchDE;
|
||||
assign CSRRdStallD = CSRReadE & MatchDE;
|
||||
|
@ -39,8 +39,7 @@ module ieu (
|
||||
// Execute Stage interface
|
||||
input logic [`XLEN-1:0] PCE,
|
||||
input logic [`XLEN-1:0] PCLinkE,
|
||||
input logic FWriteIntE,
|
||||
input logic IllegalFPUInstrE,
|
||||
input logic FWriteIntE, FCvtIntE, FCvtIntW,
|
||||
output logic [`XLEN-1:0] IEUAdrE,
|
||||
output logic MDUE, W64E,
|
||||
output logic [2:0] Funct3E,
|
||||
@ -60,7 +59,6 @@ module ieu (
|
||||
|
||||
// Writeback stage
|
||||
input logic [`XLEN-1:0] CSRReadValW, MDUResultW,
|
||||
input logic [1:0] FResSelW,
|
||||
input logic [`XLEN-1:0] FCvtIntResW,
|
||||
output logic [4:0] RdW,
|
||||
input logic [`XLEN-1:0] ReadDataW,
|
||||
@ -105,16 +103,16 @@ module ieu (
|
||||
|
||||
datapath dp(
|
||||
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE,
|
||||
.ALUControlE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .JumpE, .BranchSignedE, .IllegalFPUInstrE,
|
||||
.ALUControlE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .JumpE, .BranchSignedE,
|
||||
.PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE,
|
||||
.StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FResSelW,
|
||||
.StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW,
|
||||
.StallW, .FlushW, .RegWriteW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW,
|
||||
.CSRReadValW, .MDUResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW);
|
||||
|
||||
forward fw(
|
||||
.Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW,
|
||||
.MemReadE, .MDUE, .CSRReadE, .RegWriteM, .RegWriteW,
|
||||
.FWriteIntE, .SCE, .ForwardAE, .ForwardBE,
|
||||
.FCvtIntE, .SCE, .ForwardAE, .ForwardBE,
|
||||
.FPUStallD, .LoadStallD, .MDUStallD, .CSRRdStallD);
|
||||
endmodule
|
||||
|
||||
|
@ -230,7 +230,7 @@ module lsu (
|
||||
|
||||
mux2 #(`LLEN) UnCachedDataMux(.d0(LittleEndianReadDataWordM), .d1({{`LLEN-`XLEN{1'b0}}, DLSUBusBuffer[`XLEN-1:0]}),
|
||||
.s(SelUncachedAdr), .y(ReadDataWordMuxM));
|
||||
mux2 #(`XLEN) LsuBushwdataMux(.d0(ReadDataWordM[`XLEN-1:0]), .d1(LSUWriteDataM),
|
||||
mux2 #(`XLEN) LsuBushwdataMux(.d0(ReadDataWordM[`XLEN-1:0]), .d1(LSUWriteDataM[`XLEN-1:0]),
|
||||
.s(SelUncachedAdr), .y(LSUBusHWDATA));
|
||||
if(CACHE_ENABLED) begin : dcache
|
||||
cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN),
|
||||
|
@ -40,10 +40,10 @@ module subwordwrite (
|
||||
if (`LLEN == 128) begin:sww
|
||||
always_comb
|
||||
case(LSUFunct3M[2:0])
|
||||
2'b000: LittleEndianWriteDataM = {16{IMAFWriteDataM[7:0]}}; // sb
|
||||
2'b001: LittleEndianWriteDataM = {8{IMAFWriteDataM[15:0]}}; // sh
|
||||
2'b010: LittleEndianWriteDataM = {4{IMAFWriteDataM[31:0]}}; // sw
|
||||
2'b011: LittleEndianWriteDataM = {2{IMAFWriteDataM[63:0]}}; // sd
|
||||
3'b000: LittleEndianWriteDataM = {16{IMAFWriteDataM[7:0]}}; // sb
|
||||
3'b001: LittleEndianWriteDataM = {8{IMAFWriteDataM[15:0]}}; // sh
|
||||
3'b010: LittleEndianWriteDataM = {4{IMAFWriteDataM[31:0]}}; // sw
|
||||
3'b011: LittleEndianWriteDataM = {2{IMAFWriteDataM[63:0]}}; // sd
|
||||
default: LittleEndianWriteDataM = IMAFWriteDataM; // sq
|
||||
endcase
|
||||
end else if (`LLEN == 64) begin:sww
|
||||
|
@ -43,7 +43,7 @@ module privdec (
|
||||
output logic EcallFaultM, BreakpointFaultM,
|
||||
output logic sretM, mretM, wfiM, sfencevmaM);
|
||||
|
||||
logic IllegalPrivilegedInstrM, IllegalOrDisabledFPUInstrM;
|
||||
logic IllegalPrivilegedInstrM;
|
||||
logic WFITimeoutM;
|
||||
logic StallMQ;
|
||||
logic ebreakM, ecallM;
|
||||
@ -92,7 +92,6 @@ module privdec (
|
||||
// Fault on illegal instructions
|
||||
///////////////////////////////////////////
|
||||
assign IllegalPrivilegedInstrM = PrivilegedM & ~(sretM|mretM|ecallM|ebreakM|wfiM|sfencevmaM);
|
||||
assign IllegalOrDisabledFPUInstrM = IllegalFPUInstrM | (STATUS_FS == 2'b00);
|
||||
assign IllegalInstrFaultM = (IllegalIEUInstrFaultM & IllegalOrDisabledFPUInstrM) | IllegalPrivilegedInstrM | IllegalCSRAccessM |
|
||||
assign IllegalInstrFaultM = (IllegalIEUInstrFaultM & IllegalFPUInstrM) | IllegalPrivilegedInstrM | IllegalCSRAccessM |
|
||||
WFITimeoutM;
|
||||
endmodule
|
||||
|
@ -52,7 +52,7 @@ module privileged (
|
||||
input logic ICacheAccess,
|
||||
input logic PrivilegedM,
|
||||
input logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM,
|
||||
input logic InstrMisalignedFaultM, IllegalIEUInstrFaultD, IllegalFPUInstrD,
|
||||
input logic InstrMisalignedFaultM, IllegalIEUInstrFaultD, IllegalFPUInstrM,
|
||||
input logic LoadMisalignedFaultM,
|
||||
input logic StoreAmoMisalignedFaultM,
|
||||
input logic MTimerInt, MExtInt, SExtInt, MSwInt,
|
||||
@ -69,7 +69,6 @@ module privileged (
|
||||
input logic StoreAmoAccessFaultM,
|
||||
input logic SelHPTW,
|
||||
|
||||
output logic IllegalFPUInstrE,
|
||||
output logic [1:0] PrivilegeModeW,
|
||||
output logic [`XLEN-1:0] SATP_REGW,
|
||||
output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
|
||||
@ -88,7 +87,6 @@ module privileged (
|
||||
logic sretM, mretM;
|
||||
logic IllegalCSRAccessM;
|
||||
logic IllegalIEUInstrFaultM;
|
||||
logic IllegalFPUInstrM;
|
||||
logic InstrPageFaultM;
|
||||
logic InstrAccessFaultM;
|
||||
logic IllegalInstrFaultM;
|
||||
@ -148,9 +146,8 @@ module privileged (
|
||||
.IllegalCSRAccessM, .BigEndianM);
|
||||
|
||||
privpiperegs ppr(.clk, .reset, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
|
||||
.InstrPageFaultF, .InstrAccessFaultF, .IllegalIEUInstrFaultD, .IllegalFPUInstrD,
|
||||
.IllegalFPUInstrE,
|
||||
.InstrPageFaultM, .InstrAccessFaultM, .IllegalIEUInstrFaultM, .IllegalFPUInstrM);
|
||||
.InstrPageFaultF, .InstrAccessFaultF, .IllegalIEUInstrFaultD,
|
||||
.InstrPageFaultM, .InstrAccessFaultM, .IllegalIEUInstrFaultM);
|
||||
|
||||
trap trap(.reset,
|
||||
.InstrMisalignedFaultM, .InstrAccessFaultM, .IllegalInstrFaultM,
|
||||
|
@ -35,10 +35,9 @@ module privpiperegs (
|
||||
input logic StallD, StallE, StallM,
|
||||
input logic FlushD, FlushE, FlushM,
|
||||
input logic InstrPageFaultF, InstrAccessFaultF,
|
||||
input logic IllegalIEUInstrFaultD, IllegalFPUInstrD,
|
||||
output logic IllegalFPUInstrE,
|
||||
input logic IllegalIEUInstrFaultD,
|
||||
output logic InstrPageFaultM, InstrAccessFaultM,
|
||||
output logic IllegalIEUInstrFaultM, IllegalFPUInstrM
|
||||
output logic IllegalIEUInstrFaultM
|
||||
);
|
||||
|
||||
logic InstrPageFaultD, InstrAccessFaultD;
|
||||
@ -49,10 +48,10 @@ module privpiperegs (
|
||||
flopenrc #(2) faultregD(clk, reset, FlushD, ~StallD,
|
||||
{InstrPageFaultF, InstrAccessFaultF},
|
||||
{InstrPageFaultD, InstrAccessFaultD});
|
||||
flopenrc #(4) faultregE(clk, reset, FlushE, ~StallE,
|
||||
{IllegalIEUInstrFaultD, InstrPageFaultD, InstrAccessFaultD, IllegalFPUInstrD},
|
||||
{IllegalIEUInstrFaultE, InstrPageFaultE, InstrAccessFaultE, IllegalFPUInstrE});
|
||||
flopenrc #(4) faultregM(clk, reset, FlushM, ~StallM,
|
||||
{IllegalIEUInstrFaultE, InstrPageFaultE, InstrAccessFaultE, IllegalFPUInstrE},
|
||||
{IllegalIEUInstrFaultM, InstrPageFaultM, InstrAccessFaultM, IllegalFPUInstrM});
|
||||
flopenrc #(3) faultregE(clk, reset, FlushE, ~StallE,
|
||||
{IllegalIEUInstrFaultD, InstrPageFaultD, InstrAccessFaultD},
|
||||
{IllegalIEUInstrFaultE, InstrPageFaultE, InstrAccessFaultE});
|
||||
flopenrc #(3) faultregM(clk, reset, FlushM, ~StallM,
|
||||
{IllegalIEUInstrFaultE, InstrPageFaultE, InstrAccessFaultE},
|
||||
{IllegalIEUInstrFaultM, InstrPageFaultM, InstrAccessFaultM});
|
||||
endmodule
|
@ -94,9 +94,10 @@ module wallypipelinedcore (
|
||||
logic FWriteIntE;
|
||||
logic [`FLEN-1:0] FWriteDataM;
|
||||
logic [`XLEN-1:0] FIntResM;
|
||||
logic [`XLEN-1:0] FCvtIntResW;
|
||||
logic [`XLEN-1:0] FCvtIntResW;
|
||||
logic FCvtIntW;
|
||||
logic FDivBusyE;
|
||||
logic IllegalFPUInstrD, IllegalFPUInstrE;
|
||||
logic IllegalFPUInstrM;
|
||||
logic FRegWriteM;
|
||||
logic FPUStallD;
|
||||
logic FpLoadStoreM;
|
||||
@ -170,6 +171,7 @@ module wallypipelinedcore (
|
||||
logic BreakpointFaultM, EcallFaultM;
|
||||
logic InstrDAPageFaultF;
|
||||
logic BigEndianM;
|
||||
logic FCvtIntE;
|
||||
|
||||
ifu ifu(
|
||||
.clk, .reset,
|
||||
@ -217,7 +219,7 @@ module wallypipelinedcore (
|
||||
.IllegalBaseInstrFaultD,
|
||||
|
||||
// Execute Stage interface
|
||||
.PCE, .PCLinkE, .FWriteIntE, .IllegalFPUInstrE,
|
||||
.PCE, .PCLinkE, .FWriteIntE, .FCvtIntE,
|
||||
.IEUAdrE, .MDUE, .W64E,
|
||||
.Funct3E, .ForwardedSrcAE, .ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
||||
|
||||
@ -235,7 +237,7 @@ module wallypipelinedcore (
|
||||
.RdW, .ReadDataW(ReadDataW[`XLEN-1:0]),
|
||||
.InstrValidM,
|
||||
.FCvtIntResW,
|
||||
.FResSelW,
|
||||
.FCvtIntW,
|
||||
|
||||
// hazards
|
||||
.StallD, .StallE, .StallM, .StallW,
|
||||
@ -344,7 +346,7 @@ module wallypipelinedcore (
|
||||
.RASPredPCWrongM, .BPPredClassNonCFIWrongM,
|
||||
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .PrivilegedM,
|
||||
.InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM,
|
||||
.InstrMisalignedFaultM, .IllegalIEUInstrFaultD, .IllegalFPUInstrD,
|
||||
.InstrMisalignedFaultM, .IllegalIEUInstrFaultD,
|
||||
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
|
||||
.MTimerInt, .MExtInt, .SExtInt, .MSwInt,
|
||||
.MTIME_CLINT,
|
||||
@ -354,7 +356,7 @@ module wallypipelinedcore (
|
||||
// *** do these need to be split up into one for dmem and one for ifu?
|
||||
// instead, could we only care about the instr and F pins that come from ifu and only care about the load/store and m pins that come from dmem?
|
||||
.InstrAccessFaultF, .LoadAccessFaultM, .StoreAmoAccessFaultM, .SelHPTW,
|
||||
.IllegalFPUInstrE,
|
||||
.IllegalFPUInstrM,
|
||||
.PrivilegeModeW, .SATP_REGW,
|
||||
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS,
|
||||
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
|
||||
@ -396,21 +398,23 @@ module wallypipelinedcore (
|
||||
.FRegWriteM, // FP register write enable
|
||||
.FpLoadStoreM,
|
||||
.FStallD, // Stall the decode stage
|
||||
.FWriteIntE, // integer register write enable
|
||||
.FWriteIntE, .FCvtIntE, // integer register write enable, conversion operation
|
||||
.FWriteDataM, // Data to be written to memory
|
||||
.FIntResM, // data to be written to integer register
|
||||
.FCvtIntResW, // fp -> int conversion result to be stored in int register
|
||||
.FResSelW, // fpu result selection
|
||||
.FCvtIntW, // fpu result selection
|
||||
.FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage)
|
||||
.IllegalFPUInstrD, // Is the instruction an illegal fpu instruction
|
||||
.IllegalFPUInstrM, // Is the instruction an illegal fpu instruction
|
||||
.SetFflagsM // FPU flags (to privileged unit)
|
||||
); // floating point unit
|
||||
end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low
|
||||
assign FStallD = 0;
|
||||
assign FWriteIntE = 0;
|
||||
assign FCvtIntE = 0;
|
||||
assign FIntResM = 0;
|
||||
assign FCvtIntW = 0;
|
||||
assign FDivBusyE = 0;
|
||||
assign IllegalFPUInstrD = 1;
|
||||
assign IllegalFPUInstrM = 1;
|
||||
assign SetFflagsM = 0;
|
||||
end
|
||||
endmodule
|
||||
|
Loading…
Reference in New Issue
Block a user