From 4ff2627a509b8f474ad10b2bf57002e901c1b41e Mon Sep 17 00:00:00 2001 From: David Harris Date: Wed, 11 Jan 2023 12:18:06 -0800 Subject: [PATCH] fpu cleanup --- pipelined/src/fpu/fctrl.sv | 6 +- pipelined/src/fpu/fpu.sv | 227 ++++++++++++++----------------------- 2 files changed, 90 insertions(+), 143 deletions(-) diff --git a/pipelined/src/fpu/fctrl.sv b/pipelined/src/fpu/fctrl.sv index 0ac1181f..c968f225 100755 --- a/pipelined/src/fpu/fctrl.sv +++ b/pipelined/src/fpu/fctrl.sv @@ -50,6 +50,7 @@ module fctrl ( 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 FpLoadStoreM, // FP load or store instruction output logic FCvtIntW, output logic [4:0] Adr1D, Adr2D, Adr3D, // adresses of each input output logic [4:0] Adr1E, Adr2E, Adr3E // adresses of each input @@ -275,12 +276,13 @@ module fctrl ( if (`M_SUPPORTED & `IDIV_ON_FPU) assign IDivStartE = IntDivE; else assign IDivStartE = 0; - //assign FCvtIntE = (FResSelE == 2'b01); - // E/M pipleine register flopenrc #(14+int'(`FMTBITS)) EMCtrlReg (clk, reset, FlushM, ~StallM, {FRegWriteE, FResSelE, PostProcSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, IllegalFPUInstrE, FCvtIntE}, {FRegWriteM, FResSelM, PostProcSelM, FrmM, FmtM, OpCtrlM, FWriteIntM, IllegalFPUInstrM, FCvtIntM}); + + assign FpLoadStoreM = FResSelM[1]; + // M/W pipleine register flopenrc #(4) MWCtrlReg(clk, reset, FlushW, ~StallW, {FRegWriteM, FResSelM, FCvtIntM}, diff --git a/pipelined/src/fpu/fpu.sv b/pipelined/src/fpu/fpu.sv index 170e4688..487ce46a 100755 --- a/pipelined/src/fpu/fpu.sv +++ b/pipelined/src/fpu/fpu.sv @@ -61,7 +61,7 @@ module fpu ( output logic [`XLEN-1:0] FCvtIntResW, // convert result to to be written to integer register (to IEU) output logic FCvtIntW, // select FCvtIntRes (to IEU) output logic [`XLEN-1:0] FIntDivResultW // Result from integer division (to IEU) - ); +); // RISC-V FPU specifics: // - multiprecision support uses NAN-boxing, putting 1's in unused msbs @@ -110,6 +110,8 @@ module fpu ( logic XExpMaxE; // is the exponent all ones (max value) // Fma Signals + logic FmaAddSubE; // Multiply by 1.0 when adding or subtracting + logic [1:0] FmaZSelE; // Select Z = Y when adding or subtracting, 0 when multiplying logic [3*`NF+3:0] SmE, SmM; // Sum significand logic FmaAStickyE, FmaAStickyM; // FMA addend sticky bit output logic [`NE+1:0] SeE,SeM; // Sum exponent @@ -118,7 +120,7 @@ module fpu ( logic PsE, PsM; // Product sign logic SsE, SsM; // Sum sign logic [$clog2(3*`NF+5)-1:0] SCntE, SCntM; // LZA sum leading zero count - + // Cvt Signals logic [`NE:0] CeE, CeM; // convert intermediate expoent logic [`LOGCVTLEN-1:0] CvtShiftAmtE, CvtShiftAmtM; // how much to shift by @@ -133,37 +135,31 @@ module fpu ( logic [`NE+1:0] QeM; // fdivsqrt exponent logic DivStickyM; // fdivsqrt sticky bit logic FDivDoneE, IFDivStartE; // fdivsqrt control signals - logic [`XLEN-1:0] FIntDivResultM; // fdivsqrt integer division result (for IEU) + logic [`XLEN-1:0] FIntDivResultM; // fdivsqrt integer division result (for IEU) // result and flag signals logic [`XLEN-1:0] ClassResE; // classify result - logic [`XLEN-1:0] FIntResE; // classify result - logic [`FLEN-1:0] FpResM, FpResW; // classify result - logic [`FLEN-1:0] PostProcResM; // classify result - logic [4:0] PostProcFlgM; // classify result - logic [`FLEN-1:0] CmpFpResE; // compare result - logic [`XLEN-1:0] CmpIntResE; // compare result - logic CmpNVE; // compare invalid flag (Not Valid) - logic [`FLEN-1:0] SgnResE; // sign injection result - logic [`FLEN-1:0] PreFpResE, PreFpResM; // selected result that is ready in the memory stage + logic [`FLEN-1:0] CmpFpResE; // compare result to FPU (min/max) + logic [`XLEN-1:0] CmpIntResE; // compare result to IEU (eq/gt/geq) + logic CmpNVE; // compare invalid flag (Not Valid) + logic [`FLEN-1:0] SgnResE; // sign injection result + logic [`XLEN-1:0] FIntResE; // FPU to IEU E-stage result (classify, compare, move) + logic [`FLEN-1:0] PostProcResM; // Postprocessor output + logic [4:0] PostProcFlgM; // Postprocessor flags logic PreNVE, PreNVM; // selected flag that is ready in the memory stage - logic [`FLEN-1:0] FResultW; // final FP result being written to the FP register - // other signals - 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 - logic StallUnpackedM; + logic [`FLEN-1:0] FpResM, FpResW; // FPU preliminary result + logic [`FLEN-1:0] PreFpResE, PreFpResM; // selected result that is ready in the memory stage + logic [`FLEN-1:0] FResultW; // final FP result being written to the FP register - // DECODE STAGE + // other signals + logic [`FLEN-1:0] AlignedSrcAE; // align SrcA from IEU to the floating point format for fmv + logic [`FLEN-1:0] BoxedZeroE; // Zero value for Z for multiplication, with NaN boxing if needed + logic [`FLEN-1:0] BoxedOneE; // One value for Z for multiplication, with NaN boxing if needed + logic StallUnpackedM; // Stall unpacker outputs during multicycle fdivsqrt + logic [`FLEN-1:0] SgnExtXE; // Sign-extended X input for move to integer ////////////////////////////////////////////////////////////////////////////////////////// - // ||||||||||| - // ||| ||| - // ||| ||| - // ||| ||| - // ||| ||| - // ||| ||| - // ||||||||||| + // Decode Stage: fctrl decoder, read register file ////////////////////////////////////////////////////////////////////////////////////////// // calculate FP control signals @@ -171,8 +167,10 @@ module fpu ( .Funct3E, .IntDivE, .InstrD, .StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW, .FRM_REGW, .STATUS_FS, .FDivBusyE, .reset, .clk, .FRegWriteE, .FRegWriteM, .FRegWriteW, .FrmM, .FmtE, .FmtM, - .FDivStartE, .IDivStartE, .FWriteIntE, .FCvtIntE, .FWriteIntM, .OpCtrlE, .OpCtrlM, .IllegalFPUInstrM, .XEnD, .YEnD, .ZEnD, .XEnE, .YEnE, .ZEnE, - .FResSelE, .FResSelM, .FResSelW, .PostProcSelE, .PostProcSelM, .FCvtIntW, .Adr1D, .Adr2D, .Adr3D, .Adr1E, .Adr2E, .Adr3E); + .FDivStartE, .IDivStartE, .FWriteIntE, .FCvtIntE, .FWriteIntM, .OpCtrlE, .OpCtrlM, .FpLoadStoreM, + .IllegalFPUInstrM, .XEnD, .YEnD, .ZEnD, .XEnE, .YEnE, .ZEnE, + .FResSelE, .FResSelM, .FResSelW, .PostProcSelE, .PostProcSelM, .FCvtIntW, + .Adr1D, .Adr2D, .Adr3D, .Adr1E, .Adr2E, .Adr3E); // FP register file fregfile fregfile (.clk, .reset, .we4(FRegWriteW), @@ -185,29 +183,21 @@ module fpu ( flopenrc #(`FLEN) DEReg2(clk, reset, FlushE, ~StallE, FRD2D, FRD2E); flopenrc #(`FLEN) DEReg3(clk, reset, FlushE, ~StallE, FRD3D, FRD3E); - // EXECUTION STAGE - ////////////////////////////////////////////////////////////////////////////////////////// - // |||||||||||| - // ||| - // ||| - // ||||||||| - // ||| - // ||| - // |||||||||||| + // Execute Stage: hazards, forwarding, unpacking, execution units ////////////////////////////////////////////////////////////////////////////////////////// - // Hazard unit for FPU - // - determines if any forwarding or stalls are needed - fhazard fhazard(.Adr1D, .Adr2D, .Adr3D, .Adr1E, .Adr2E, .Adr3E, .FRegWriteE, .FRegWriteM, .FRegWriteW, .RdE, .RdM, .RdW, .FResSelM, - .XEnD, .YEnD, .ZEnD, .FPUStallD, .ForwardXE, .ForwardYE, .ForwardZE); + // Hazard unit for FPU: determines if any forwarding or stalls are needed + fhazard fhazard(.Adr1D, .Adr2D, .Adr3D, .Adr1E, .Adr2E, .Adr3E, + .FRegWriteE, .FRegWriteM, .FRegWriteW, .RdE, .RdM, .RdW, .FResSelM, + .XEnD, .YEnD, .ZEnD, .FPUStallD, .ForwardXE, .ForwardYE, .ForwardZE); // forwarding muxs mux3 #(`FLEN) fxemux (FRD1E, FResultW, PreFpResM, ForwardXE, XE); mux3 #(`FLEN) fyemux (FRD2E, FResultW, PreFpResM, ForwardYE, PreYE); mux3 #(`FLEN) fzemux (FRD3E, FResultW, PreFpResM, ForwardZE, PreZE); - + // Select NAN-boxed value of Y = 1.0 in proper format for fma to add/subtract X*Y+Z generate if(`FPSIZES == 1) assign BoxedOneE = {2'b0, {`NE-1{1'b1}}, (`NF)'(0)}; else if(`FPSIZES == 2) @@ -218,11 +208,11 @@ module fpu ( {{`FLEN-`H_LEN{1'b1}}, 2'b0, {`H_NE-1{1'b1}}, (`H_NF)'(0)}, {2'b0, {`NE-1{1'b1}}, (`NF)'(0)}, FmtE, BoxedOneE); // NaN boxing zeroes endgenerate - - - mux2 #(`FLEN) fyaddmux (PreYE, BoxedOneE, OpCtrlE[2]&OpCtrlE[1]&(FResSelE==2'b01)&(PostProcSelE==2'b10), YE); // Force Z to be 0 for multiply instructions + assign FmaAddSubE = OpCtrlE[2]&OpCtrlE[1]&(FResSelE==2'b01)&(PostProcSelE==2'b10); + mux2 #(`FLEN) fyaddmux (PreYE, BoxedOneE, FmaAddSubE, YE); // Force Y to be 1 for add/subtract - // Force Z to be 0 for multiply instructions + // Select NAN-boxed value of Z = 0.0 in proper format for FMA for multiply X*Y+Z + // For add and subtract, Z comes from second source operand generate if(`FPSIZES == 1) assign BoxedZeroE = 0; else if(`FPSIZES == 2) @@ -233,74 +223,49 @@ module fpu ( {{`FLEN-`H_LEN{1'b1}}, {`H_LEN{1'b0}}}, (`FLEN)'(0), FmtE, BoxedZeroE); // NaN boxing zeroes endgenerate + assign FmaZSelE = {OpCtrlE[2]&OpCtrlE[1], OpCtrlE[2]&~OpCtrlE[1]}; + mux3 #(`FLEN) fzmulmux (PreZE, BoxedZeroE, PreYE, FmaZSelE, ZE); - mux3 #(`FLEN) fzmulmux (PreZE, BoxedZeroE, PreYE, {OpCtrlE[2]&OpCtrlE[1], OpCtrlE[2]&~OpCtrlE[1]}, ZE); - - // unpack unit - // - splits FP inputs into their various parts - // - does some classifications (SNaN, NaN, Subnorm, Norm, Zero, Infifnity) + // unpack unit: splits FP inputs into their parts and classifies SNaN, NaN, Subnorm, Norm, Zero, Infifnity unpack unpack (.X(XE), .Y(YE), .Z(ZE), .Fmt(FmtE), .Xs(XsE), .Ys(YsE), .Zs(ZsE), - .Xe(XeE), .Ye(YeE), .Ze(ZeE), .Xm(XmE), .Ym(YmE), .Zm(ZmE), .YEn(YEnE), - .XNaN(XNaNE), .YNaN(YNaNE), .ZNaN(ZNaNE), .XSNaN(XSNaNE), .XEn(XEnE), - .YSNaN(YSNaNE), .ZSNaN(ZSNaNE), .XSubnorm(XSubnormE), - .XZero(XZeroE), .YZero(YZeroE), .ZZero(ZZeroE), .XInf(XInfE), .YInf(YInfE), - .ZEn(ZEnE), .ZInf(ZInfE), .XExpMax(XExpMaxE)); + .Xe(XeE), .Ye(YeE), .Ze(ZeE), .Xm(XmE), .Ym(YmE), .Zm(ZmE), .YEn(YEnE), + .XNaN(XNaNE), .YNaN(YNaNE), .ZNaN(ZNaNE), .XSNaN(XSNaNE), .XEn(XEnE), + .YSNaN(YSNaNE), .ZSNaN(ZSNaNE), .XSubnorm(XSubnormE), + .XZero(XZeroE), .YZero(YZeroE), .ZZero(ZZeroE), .XInf(XInfE), .YInf(YInfE), + .ZEn(ZEnE), .ZInf(ZInfE), .XExpMax(XExpMaxE)); - // fused multiply add - // - fadd/fsub - // - fmul - // - fmadd/fnmadd/fmsub/fnmsub - fma fma (.Xs(XsE), .Ys(YsE), .Zs(ZsE), - .Xe(XeE), .Ye(YeE), .Ze(ZeE), - .Xm(XmE), .Ym(YmE), .Zm(ZmE), - .XZero(XZeroE), .YZero(YZeroE), .ZZero(ZZeroE), - .OpCtrl(OpCtrlE), - .As(AsE), .Ps(PsE), .Ss(SsE), .Se(SeE), - .Sm(SmE), - .InvA(InvAE), .SCnt(SCntE), - .ASticky(FmaAStickyE)); + // fused multiply add: fadd/sub, fmul, fmadd/fnmadd/fmsub/fnmsub + fma fma (.Xs(XsE), .Ys(YsE), .Zs(ZsE), .Xe(XeE), .Ye(YeE), .Ze(ZeE), .Xm(XmE), .Ym(YmE), .Zm(ZmE), + .XZero(XZeroE), .YZero(YZeroE), .ZZero(ZZeroE), .OpCtrl(OpCtrlE), + .As(AsE), .Ps(PsE), .Ss(SsE), .Se(SeE), .Sm(SmE), .InvA(InvAE), .SCnt(SCntE), .ASticky(FmaAStickyE)); - // divide and squareroot - // - fdiv - // - fsqrt - // *** add other opperations + // divide and square root: fdiv, fsqrt, optionally integer division fdivsqrt fdivsqrt(.clk, .reset, .FmtE, .XmE, .YmE, .XeE, .YeE, .SqrtE(OpCtrlE[0]), .SqrtM(OpCtrlM[0]), - .XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE, .FDivStartE, .IDivStartE, .XsE, - .ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .Funct3M, .IntDivE, .W64E, - .StallM, .FlushE, .DivStickyM, .FDivBusyE, .IFDivStartE, .FDivDoneE, .QeM, - .QmM, .FIntDivResultM /*, .DivDone(DivDoneM) */); + .XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE, .FDivStartE, .IDivStartE, .XsE, + .ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .Funct3M, .IntDivE, .W64E, + .StallM, .FlushE, .DivStickyM, .FDivBusyE, .IFDivStartE, .FDivDoneE, .QeM, + .QmM, .FIntDivResultM); - // - // compare - // - fmin/fmax - // - flt/fle/feq + // compare: fmin/fmax, flt/fle/feq fcmp fcmp (.Fmt(FmtE), .OpCtrl(OpCtrlE), .Xs(XsE), .Ys(YsE), .Xe(XeE), .Ye(YeE), - .Xm(XmE), .Ym(YmE), .XZero(XZeroE), .YZero(YZeroE), .XNaN(XNaNE), .YNaN(YNaNE), - .XSNaN(XSNaNE), .YSNaN(YSNaNE), .X(XE), .Y(YE), .CmpNV(CmpNVE), - .CmpFpRes(CmpFpResE), .CmpIntRes(CmpIntResE)); - // sign injection - // - fsgnj/fsgnjx/fsgnjn + .Xm(XmE), .Ym(YmE), .XZero(XZeroE), .YZero(YZeroE), .XNaN(XNaNE), .YNaN(YNaNE), + .XSNaN(XSNaNE), .YSNaN(YSNaNE), .X(XE), .Y(YE), .CmpNV(CmpNVE), + .CmpFpRes(CmpFpResE), .CmpIntRes(CmpIntResE)); + + // sign injection: fsgnj/fsgnjx/fsgnjn fsgninj fsgninj(.OpCtrl(OpCtrlE[1:0]), .Xs(XsE), .Ys(YsE), .X(XE), .Fmt(FmtE), .SgnRes(SgnResE)); - // classify - // - fclass + // classify: fclass fclassify fclassify (.Xs(XsE), .XSubnorm(XSubnormE), .XZero(XZeroE), .XNaN(XNaNE), - .XInf(XInfE), .XSNaN(XSNaNE), .ClassRes(ClassResE)); + .XInf(XInfE), .XSNaN(XSNaNE), .ClassRes(ClassResE)); - // convert - // - fcvt.*.* + // convert: fcvt.*.* fcvt fcvt (.Xs(XsE), .Xe(XeE), .Xm(XmE), .Int(ForwardedSrcAE), .OpCtrl(OpCtrlE), - .ToInt(FWriteIntE), .XZero(XZeroE), .Fmt(FmtE), .Ce(CeE), - .ShiftAmt(CvtShiftAmtE), .ResSubnormUf(CvtResSubnormUfE), .Cs(CsE), .IntZero(IntZeroE), - .LzcIn(CvtLzcInE)); + .ToInt(FWriteIntE), .XZero(XZeroE), .Fmt(FmtE), .Ce(CeE), .ShiftAmt(CvtShiftAmtE), + .ResSubnormUf(CvtResSubnormUfE), .Cs(CsE), .IntZero(IntZeroE), .LzcIn(CvtLzcInE)); - // data to be stored in memory - to IEU - // - FP uses NaN-blocking format - // - if there are any unsused bits the most significant bits are filled with 1s - - flopenrc #(`FLEN) FWriteDataMReg (clk, reset, FlushM, ~StallM, YE, FWriteDataM); - // NaN Block SrcA + // NaN Box SrcA to convert integer to requested FP size generate if(`FPSIZES == 1) assign AlignedSrcAE = {{`FLEN-`XLEN{1'b1}}, ForwardedSrcAE}; else if(`FPSIZES == 2) @@ -317,8 +282,6 @@ module fpu ( assign PreNVE = CmpNVE&(OpCtrlE[2]|FWriteIntE); // select the result that may be written to the integer register - to IEU - - logic [`FLEN-1:0] SgnExtXE; generate if(`FPSIZES == 1) assign SgnExtXE = XE; @@ -328,20 +291,18 @@ module fpu ( mux4 #(`FLEN) fmulzeromux ({{`FLEN-`H_LEN{XsE}}, XE[`H_LEN-1:0]}, {{`FLEN-`S_LEN{XsE}}, XE[`S_LEN-1:0]}, {{`FLEN-`D_LEN{XsE}}, XE[`D_LEN-1:0]}, - XE, FmtE, SgnExtXE); // NaN boxing zeroes + XE, FmtE, SgnExtXE); endgenerate if (`FLEN>`XLEN) assign IntSrcXE = SgnExtXE[`XLEN-1:0]; else assign IntSrcXE = {{`XLEN-`FLEN{XsE}}, SgnExtXE}; - mux3 #(`XLEN) IntResMux (ClassResE, IntSrcXE, CmpIntResE, {~FResSelE[1], FResSelE[0]}, FIntResE); - // *** DH 5/25/22: CvtRes will move to mem stage. Premux in execute to save area, then make sure stalls are ok - // *** make sure the fpu matches the chapter diagram // E/M pipe registers - assign StallUnpackedM = StallM | (FDivBusyE & ~IFDivStartE | FDivDoneE); // Need to stall during divsqrt iterations to avoid capturing bad flags from stale forwarded sources + // Need to stall during divsqrt iterations to avoid capturing bad flags from stale forwarded sources + assign StallUnpackedM = StallM | (FDivBusyE & ~IFDivStartE | FDivDoneE); flopenrc #(`NF+1) EMFpReg2 (clk, reset, FlushM, ~StallM, XmE, XmM); flopenrc #(`NF+1) EMFpReg3 (clk, reset, FlushM, ~StallM, YmE, YmM); @@ -349,57 +310,41 @@ module fpu ( flopenrc #(`XLEN) EMFpReg6 (clk, reset, FlushM, ~StallM, FIntResE, FIntResM); flopenrc #(`FLEN) EMFpReg7 (clk, reset, FlushM, ~StallM, PreFpResE, PreFpResM); flopenr #(13) EMFpReg5 (clk, reset, ~StallUnpackedM, - {XsE, YsE, XZeroE, YZeroE, XInfE, YInfE, ZInfE, XNaNE, YNaNE, ZNaNE, XSNaNE, YSNaNE, ZSNaNE}, - {XsM, YsM, XZeroM, YZeroM, XInfM, YInfM, ZInfM, XNaNM, YNaNM, ZNaNM, XSNaNM, YSNaNM, ZSNaNM}); + {XsE, YsE, XZeroE, YZeroE, XInfE, YInfE, ZInfE, XNaNE, YNaNE, ZNaNE, XSNaNE, YSNaNE, ZSNaNE}, + {XsM, YsM, XZeroM, YZeroM, XInfM, YInfM, ZInfM, XNaNM, YNaNM, ZNaNM, XSNaNM, YSNaNM, ZSNaNM}); flopenrc #(1) EMRegCmpFlg (clk, reset, FlushM, ~StallM, PreNVE, PreNVM); flopenrc #(3*`NF+4) EMRegFma2(clk, reset, FlushM, ~StallM, SmE, SmM); - flopenrc #($clog2(3*`NF+5)+7+`NE) EMRegFma4(clk, reset, FlushM, ~StallM, - {FmaAStickyE, InvAE, SCntE, AsE, PsE, SsE, SeE}, - {FmaAStickyM, InvAM, SCntM, AsM, PsM, SsM, SeM}); + flopenrc #($clog2(3*`NF+5)+7+`NE) EMRegFma4(clk, reset, FlushM, ~StallM, + {FmaAStickyE, InvAE, SCntE, AsE, PsE, SsE, SeE}, + {FmaAStickyM, InvAM, SCntM, AsM, PsM, SsM, SeM}); flopenrc #(`NE+`LOGCVTLEN+`CVTLEN+4) EMRegCvt(clk, reset, FlushM, ~StallM, - {CeE, CvtShiftAmtE, CvtResSubnormUfE, CsE, IntZeroE, CvtLzcInE}, - {CeM, CvtShiftAmtM, CvtResSubnormUfM, CsM, IntZeroM, CvtLzcInM}); - - // BEGIN MEMORY STAGE + {CeE, CvtShiftAmtE, CvtResSubnormUfE, CsE, IntZeroE, CvtLzcInE}, + {CeM, CvtShiftAmtM, CvtResSubnormUfM, CsM, IntZeroM, CvtLzcInM}); + flopenrc #(`FLEN) FWriteDataMReg (clk, reset, FlushM, ~StallM, YE, FWriteDataM); ////////////////////////////////////////////////////////////////////////////////////////// - // ||| ||| - // |||||| |||||| - // ||| ||| ||| ||| - // ||| ||||| ||| - // ||| ||| ||| - // ||| ||| - // ||| ||| + // Memory Stage: postprocessor and result muxes ////////////////////////////////////////////////////////////////////////////////////////// - assign FpLoadStoreM = FResSelM[1]; - postprocess postprocess(.Xs(XsM), .Ys(YsM), .Xm(XmM), .Ym(YmM), .Zm(ZmM), .Frm(FrmM), .Fmt(FmtM), - .FmaASticky(FmaAStickyM), .XZero(XZeroM), .YZero(YZeroM), .XInf(XInfM), .YInf(YInfM), .DivQm(QmM), .FmaSs(SsM), - .ZInf(ZInfM), .XNaN(XNaNM), .YNaN(YNaNM), .ZNaN(ZNaNM), .XSNaN(XSNaNM), .YSNaN(YSNaNM), .ZSNaN(ZSNaNM), .FmaSm(SmM), .DivQe(QeM), /*.DivDone(DivDoneM), */ - .FmaAs(AsM), .FmaPs(PsM), .OpCtrl(OpCtrlM), .FmaSCnt(SCntM), .FmaSe(SeM), - .CvtCe(CeM), .CvtResSubnormUf(CvtResSubnormUfM),.CvtShiftAmt(CvtShiftAmtM), .CvtCs(CsM), .ToInt(FWriteIntM), .DivS(DivStickyM), - .CvtLzcIn(CvtLzcInM), .IntZero(IntZeroM), .PostProcSel(PostProcSelM), .PostProcRes(PostProcResM), .PostProcFlg(PostProcFlgM), .FCvtIntRes(FCvtIntResM)); + .FmaASticky(FmaAStickyM), .XZero(XZeroM), .YZero(YZeroM), .XInf(XInfM), .YInf(YInfM), .DivQm(QmM), .FmaSs(SsM), + .ZInf(ZInfM), .XNaN(XNaNM), .YNaN(YNaNM), .ZNaN(ZNaNM), .XSNaN(XSNaNM), .YSNaN(YSNaNM), .ZSNaN(ZSNaNM), + .FmaSm(SmM), .DivQe(QeM), .FmaAs(AsM), .FmaPs(PsM), .OpCtrl(OpCtrlM), .FmaSCnt(SCntM), .FmaSe(SeM), + .CvtCe(CeM), .CvtResSubnormUf(CvtResSubnormUfM),.CvtShiftAmt(CvtShiftAmtM), .CvtCs(CsM), + .ToInt(FWriteIntM), .DivS(DivStickyM), .CvtLzcIn(CvtLzcInM), .IntZero(IntZeroM), + .PostProcSel(PostProcSelM), .PostProcRes(PostProcResM), .PostProcFlg(PostProcFlgM), .FCvtIntRes(FCvtIntResM)); // FPU flag selection - to privileged - mux2 #(5) FPUFlgMux ({PreNVM&~FResSelM[1], 4'b0}, PostProcFlgM, ~FResSelM[1]&FResSelM[0], SetFflagsM); - mux2 #(`FLEN) FPUResMux (PreFpResM, PostProcResM, FResSelM[0], FpResM); + mux2 #(5) FPUFlgMux({PreNVM&~FResSelM[1], 4'b0}, PostProcFlgM, ~FResSelM[1]&FResSelM[0], SetFflagsM); + mux2 #(`FLEN) FPUResMux(PreFpResM, PostProcResM, FResSelM[0], FpResM); // M/W pipe registers flopenrc #(`FLEN) MWRegFp(clk, reset, FlushW, ~StallW, FpResM, FpResW); flopenrc #(`XLEN) MWRegIntCvtRes(clk, reset, FlushW, ~StallW, FCvtIntResM, FCvtIntResW); flopenrc #(`XLEN) MWRegIntDivRes(clk, reset, FlushW, ~StallW, FIntDivResultM, FIntDivResultW); - // BEGIN WRITEBACK STAGE - ////////////////////////////////////////////////////////////////////////////////////////// - // ||| ||| - // ||| ||| - // ||| ||| ||| - // ||| ||||| ||| - // ||| ||| ||| ||| - // |||||| |||||| - // ||| ||| + // Writeback Stage: result mux ////////////////////////////////////////////////////////////////////////////////////////// // select the result to be written to the FP register