2021-04-08 17:55:25 +00:00
|
|
|
// `include "../../config/rv64icfd/wally-config.vh"
|
2021-04-04 18:09:13 +00:00
|
|
|
|
|
|
|
module fpu (
|
|
|
|
//input logic [2:0] FrmD,
|
|
|
|
input logic [2:0] FRM_REGW, // Rounding mode from CSR
|
|
|
|
input logic reset,
|
|
|
|
//input logic clear, // *** what is this used for?
|
|
|
|
input logic clk,
|
|
|
|
input logic [31:0] InstrD,
|
|
|
|
input logic [`XLEN-1:0] SrcAE, // Integer input being processed
|
|
|
|
input logic [`XLEN-1:0] SrcAM, // Integer input being written into fpreg
|
|
|
|
output logic [4:0] SetFflagsM,
|
|
|
|
output logic [31:0] FSROutW,
|
|
|
|
output logic DivSqrtDoneE,
|
|
|
|
output logic FInvalInstrD,
|
|
|
|
output logic [`XLEN-1:0] FPUResultW);
|
|
|
|
|
|
|
|
//NOTE:
|
|
|
|
//For readability and ease of modification, logic signals will be
|
|
|
|
//instantiated as they occur within the pipeline. This will keep local
|
|
|
|
//signals, modules, and combinational logic closely defined.
|
|
|
|
|
|
|
|
//used for OSU DP-size hardware to wally XLEN interfacing
|
|
|
|
integer XLENDIFF;
|
|
|
|
assign XLENDIFF = `XLEN - 64;
|
|
|
|
integer XLENDIFFN;
|
|
|
|
assign XLENDIFFN = 63 - `XLEN;
|
|
|
|
|
|
|
|
//#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
|
|
|
|
//BEGIN PIPELINE CONTROL LOGIC
|
|
|
|
//
|
|
|
|
|
|
|
|
logic PipeEnableDE;
|
|
|
|
logic PipeEnableEM;
|
|
|
|
logic PipeEnableMW;
|
|
|
|
logic PipeClearDE;
|
|
|
|
logic PipeClearEM;
|
|
|
|
logic PipeClearMW;
|
|
|
|
|
|
|
|
//temporarily assign pipe clear and enable signals
|
|
|
|
//to never flush & always be running
|
|
|
|
assign PipeClear = 1'b0;
|
|
|
|
assign PipeEnable = 1'b1;
|
|
|
|
always_comb begin
|
|
|
|
|
|
|
|
PipeEnableDE = PipeEnable;
|
|
|
|
PipeEnableEM = PipeEnable;
|
|
|
|
PipeEnableMW = PipeEnable;
|
|
|
|
PipeClearDE = PipeClear;
|
|
|
|
PipeClearEM = PipeClear;
|
|
|
|
PipeClearMW = PipeClear;
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
//
|
|
|
|
//END PIPELINE CONTROL LOGIC
|
|
|
|
//#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#
|
|
|
|
|
|
|
|
//#########################################
|
|
|
|
//BEGIN DECODE STAGE
|
|
|
|
//
|
|
|
|
|
|
|
|
//wally-spec D stage control logic signal instantiation
|
|
|
|
logic IllegalFPUInstrFaultD;
|
|
|
|
logic FRegWriteD;
|
|
|
|
logic [2:0] FResultSelD;
|
|
|
|
logic [2:0] FrmD;
|
|
|
|
logic PD;
|
|
|
|
logic DivSqrtStartD;
|
|
|
|
logic [3:0] OpCtrlD;
|
|
|
|
logic WriteIntD;
|
|
|
|
|
|
|
|
//top-level controller for FPU
|
|
|
|
fctrl ctrl (.Funct7D(InstrD[31:25]), .OpD(InstrD[6:0]), .Rs2D(InstrD[24:20]), .Rs1D(InstrD[19:15]), .FrmW(InstrD[14:12]), .WriteEnD(FRegWriteD), .WriteSelD(FResultSelD), .FmtD(PD), .*);
|
|
|
|
|
|
|
|
//instantiation of D stage regfile signals (includes some W stage signals
|
|
|
|
//for easy reference)
|
|
|
|
logic [2:0] FrmW;
|
|
|
|
logic WriteEnW;
|
|
|
|
logic [4:0] RdW, Rs1D, Rs2D, Rs3D;
|
|
|
|
logic [`XLEN-1:0] WriteDataW;
|
|
|
|
logic [`XLEN-1:0] ReadData1D, ReadData2D, ReadData3D;
|
|
|
|
|
|
|
|
//regfile instantiation
|
|
|
|
freg3adr fpregfile (FrmW, reset, PipeClear, clk, RdW, WriteEnW, Rs1D, Rs2D, Rs3D, WriteDataW, ReadData1D, ReadData2D, ReadData3D);
|
|
|
|
|
|
|
|
always_comb begin
|
|
|
|
FrmW = InstrD[14:12];
|
|
|
|
end
|
|
|
|
|
|
|
|
//
|
|
|
|
//END DECODE STAGE
|
|
|
|
//#########################################
|
|
|
|
|
|
|
|
//*****************************************
|
|
|
|
//BEGIN D/E PIPE
|
|
|
|
//
|
|
|
|
|
|
|
|
//wally-spec E stage control logic signal instantiation
|
|
|
|
logic FRegWriteE;
|
|
|
|
logic [2:0] FResultSelE;
|
|
|
|
logic [2:0] FrmE;
|
|
|
|
logic PE;
|
|
|
|
logic DivSqrtStartE;
|
|
|
|
logic [3:0] OpCtrlE;
|
|
|
|
|
|
|
|
//instantiation of E stage regfile signals
|
|
|
|
logic [4:0] RdE;
|
|
|
|
logic [`XLEN-1:0] ReadData1E, ReadData2E, ReadData3E;
|
|
|
|
|
|
|
|
//instantiation of E/M stage div/sqrt signals
|
|
|
|
logic DivSqrtDone, DivDenormM;
|
|
|
|
logic [63:0] DivResultM;
|
|
|
|
logic [4:0] DivFlagsM;
|
|
|
|
logic [63:0] DivOp1, DivOp2;
|
|
|
|
logic [2:0] DivFrm;
|
|
|
|
logic DivOpType;
|
|
|
|
logic DivP;
|
|
|
|
logic DivOvEn, DivUnEn;
|
|
|
|
logic DivStart;
|
|
|
|
|
|
|
|
//instantiate E stage FMA signals here
|
|
|
|
|
|
|
|
//instantiation of E stage add/cvt signals
|
|
|
|
logic [63:0] AddSumE, AddSumTcE;
|
|
|
|
logic [3:0] AddSelInvE;
|
|
|
|
logic [10:0] AddExpPostSumE;
|
|
|
|
logic AddCorrSignE, AddOp1NormE, AddOp2NormE, AddOpANormE, AddOpBNormE, AddInvalidE;
|
|
|
|
logic AddDenormInE, AddSwapE, AddNormOvflowE, AddSignAE;
|
|
|
|
logic [63:0] AddFloat1E, AddFloat2E;
|
|
|
|
logic [10:0] AddExp1DenormE, AddExp2DenormE, AddExponentE;
|
|
|
|
logic [63:0] AddOp1E, AddOp2E;
|
|
|
|
logic [2:0] AddRmE;
|
|
|
|
logic [3:0] AddOpTypeE;
|
|
|
|
logic AddPE, AddOvEnE, AddUnEnE;
|
|
|
|
|
|
|
|
//instantiation of E stage cmp signals
|
|
|
|
logic [7:0] WE, XE;
|
|
|
|
logic ANaNE, BNaNE, AzeroE, BzeroE;
|
|
|
|
logic [63:0] CmpOp1E, CmpOp2E;
|
|
|
|
logic [1:0] CmpSelE;
|
|
|
|
|
|
|
|
//instantiation of E/M stage fsgn signals (due to bypass logic)
|
|
|
|
logic [63:0] SgnOp1E, SgnOp2E;
|
|
|
|
logic [1:0] SgnOpCodeE, SgnOpCodeM;
|
|
|
|
logic [63:0] SgnResultE, SgnResultM;
|
|
|
|
logic [4:0] SgnFlagsE, SgnFlagsM;
|
|
|
|
|
|
|
|
//*****************
|
|
|
|
//fpregfile D/E pipe registers
|
|
|
|
//*****************
|
|
|
|
flopenrc #(64) DEReg1(clk, reset, PipeClearDE, PipeEnableDE, ReadData1D, ReadData1E);
|
|
|
|
flopenrc #(64) DEReg2(clk, reset, PipeClearDE, PipeEnableDE, ReadData2D, ReadData2E);
|
|
|
|
flopenrc #(64) DEReg3(clk, reset, PipeClearDE, PipeEnableDE, ReadData3D, ReadData3E);
|
|
|
|
|
|
|
|
//*****************
|
|
|
|
//other D/E pipe registers
|
|
|
|
//*****************
|
|
|
|
flopenrc #(1) DEReg4(clk, reset, PipeClearDE, PipeEnableDE, FRegWriteD, FRegWriteE);
|
|
|
|
flopenrc #(3) DEReg5(clk, reset, PipeClearDE, PipeEnableDE, FResultSelD, FResultSelE);
|
|
|
|
flopenrc #(3) DEReg6(clk, reset, PipeClearDE, PipeEnableDE, FrmD, FrmE);
|
|
|
|
flopenrc #(1) DEReg7(clk, reset, PipeClearDE, PipeEnableDE, PD, PE);
|
|
|
|
flopenrc #(4) DEReg8(clk, reset, PipeClearDE, PipeEnableDE, OpCtrlD, OpCtrlE);
|
|
|
|
flopenrc #(1) DEReg9(clk, reset, PipeClearDE, PipeEnableDE, DivSqrtStartD, DivSqrtStartE);
|
|
|
|
|
|
|
|
//
|
|
|
|
//END D/E PIPE
|
|
|
|
//*****************************************
|
|
|
|
|
|
|
|
//#########################################
|
|
|
|
//BEGIN EXECUTION STAGE
|
|
|
|
//
|
|
|
|
|
|
|
|
//fma1 ();
|
|
|
|
|
|
|
|
//first and only instance of floating-point divider
|
|
|
|
fpdiv fpdivsqrt (.*);
|
|
|
|
|
|
|
|
//first of two-stage instance of floating-point add/cvt unit
|
|
|
|
fpuaddcvt1 fpadd1 (AddSumE, AddSumTcE, AddSelInvE, AddExpPostSumE, AddCorrSignE, AddOp1NormE, AddOp2NormE, AddOpANormE, AddOpBNormE, AddInvalidE, AddDenormInE, AddConvertE, AddSwapE, AddNormOvflowE, AddSignAE, AddFloat1E, AddFloat2E, AddExp1DenormE, AddExp2DenormE, AddExponentE, AddOp1E, AddOp2E, AddRmE, AddOpTypeE, AddPE, AddOvEnE, AddUnEnE);
|
|
|
|
|
|
|
|
//first of two-stage instance of floating-point comparator
|
|
|
|
fpucmp1 fpcmp1 (WE, XE, ANaNE, BNaNE, AzeroE, BzeroE, CmpOp1E, CmpOp2E, CmpSelE);
|
|
|
|
|
|
|
|
//first and only instance of floating-point sign converter
|
|
|
|
fpusgn fpsgn (.*);
|
|
|
|
|
|
|
|
//interface between XLEN size datapath and double-precision sized
|
|
|
|
//floating-point results
|
|
|
|
//
|
|
|
|
//define offsets for LSB zero extension or truncation
|
|
|
|
always_comb begin
|
|
|
|
|
|
|
|
//truncate to 64 bits
|
|
|
|
//(causes warning during compilation - case never reached)
|
|
|
|
if(`XLEN > 64) begin
|
|
|
|
DivOp1 <= ReadData1E[`XLEN-1:`XLEN-64];
|
|
|
|
DivOp2 <= ReadData2E[`XLEN-1:`XLEN-64];
|
|
|
|
AddOp1E <= ReadData1E[`XLEN-1:`XLEN-64];
|
|
|
|
AddOp2E <= ReadData2E[`XLEN-1:`XLEN-64];
|
|
|
|
CmpOp1E <= ReadData1E[`XLEN-1:`XLEN-64];
|
|
|
|
CmpOp2E <= ReadData2E[`XLEN-1:`XLEN-64];
|
|
|
|
SgnOp1E <= ReadData1E[`XLEN-1:`XLEN-64];
|
|
|
|
SgnOp2E <= ReadData2E[`XLEN-1:`XLEN-64];
|
|
|
|
end
|
|
|
|
//zero extend to 64 bits
|
|
|
|
else begin
|
|
|
|
DivOp1 <= {ReadData1E,{64-`XLEN{1'b0}}};
|
|
|
|
DivOp2 <= {ReadData2E,{64-`XLEN{1'b0}}};
|
|
|
|
AddOp1E <= {ReadData1E,{64-`XLEN{1'b0}}};
|
|
|
|
AddOp2E <= {ReadData2E,{64-`XLEN{1'b0}}};
|
|
|
|
CmpOp1E <= {ReadData1E,{64-`XLEN{1'b0}}};
|
|
|
|
CmpOp2E <= {ReadData2E,{64-`XLEN{1'b0}}};
|
|
|
|
SgnOp1E <= {ReadData1E,{64-`XLEN{1'b0}}};
|
|
|
|
SgnOp2E <= {ReadData2E,{64-`XLEN{1'b0}}};
|
|
|
|
end
|
|
|
|
|
|
|
|
//assign op codes
|
|
|
|
AddOpTypeE[3:0] <= OpCtrlE[3:0];
|
|
|
|
CmpSelE[1:0] <= OpCtrlE[1:0];
|
|
|
|
DivOpType <= OpCtrlE[0];
|
|
|
|
SgnOpCodeE[1:0] <= OpCtrlE[1:0];
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
//E stage control signal interfacing between wally spec and OSU fp hardware
|
|
|
|
//op codes
|
|
|
|
|
|
|
|
//
|
|
|
|
//END EXECUTION STAGE
|
|
|
|
//#########################################
|
|
|
|
|
|
|
|
//*****************************************
|
|
|
|
//BEGIN E/M PIPE
|
|
|
|
//
|
|
|
|
|
|
|
|
//wally-spec M stage control logic signal instantiation
|
|
|
|
logic FRegWriteM;
|
|
|
|
logic [2:0] FResultSelM;
|
|
|
|
logic [2:0] FrmM;
|
|
|
|
logic PM;
|
|
|
|
logic [3:0] OpCtrlM;
|
|
|
|
|
|
|
|
//instantiate M stage FMA signals here
|
|
|
|
|
|
|
|
//instantiation of M stage regfile signals
|
|
|
|
logic [4:0] RdM;
|
|
|
|
logic [`XLEN-1:0] ReadData1M, ReadData2M, ReadData3M;
|
|
|
|
|
|
|
|
//instantiation of M stage add/cvt signals
|
|
|
|
logic [63:0] AddResultM;
|
|
|
|
logic [4:0] AddFlagsM;
|
|
|
|
logic AddDenormM;
|
|
|
|
logic [63:0] AddSumM, AddSumTcM;
|
|
|
|
logic [3:0] AddSelInvM;
|
|
|
|
logic [10:0] AddExpPostSumM;
|
|
|
|
logic AddCorrSignM, AddOp1NormM, AddOp2NormM, AddOpANormM, AddOpBNormM, AddInvalidM;
|
|
|
|
logic AddDenormInM, AddSwapM, AddNormOvflowM, AddSignAM;
|
|
|
|
logic [63:0] AddFloat1M, AddFloat2M;
|
|
|
|
logic [10:0] AddExp1DenormM, AddExp2DenormM, AddExponentM;
|
|
|
|
logic [63:0] AddOp1M, AddOp2M;
|
|
|
|
logic [2:0] AddRmM;
|
|
|
|
logic [3:0] AddOpTypeM;
|
|
|
|
logic AddPM, AddOvEnM, AddUnEnM;
|
|
|
|
|
|
|
|
//instantiation of M stage cmp signals
|
|
|
|
logic CmpInvalidM;
|
|
|
|
logic [1:0] CmpFCCM;
|
|
|
|
logic [7:0] WM, XM;
|
|
|
|
logic ANaNM, BNaNM, AzeroM, BzeroM;
|
|
|
|
logic [63:0] CmpOp1M, CmpOp2M;
|
|
|
|
logic [1:0] CmpSelM;
|
|
|
|
|
|
|
|
//*****************
|
|
|
|
//fma E/M pipe registers
|
|
|
|
//*****************
|
|
|
|
|
|
|
|
//*****************
|
|
|
|
//fpadd E/M pipe registers
|
|
|
|
//*****************
|
|
|
|
flopenrc #(64) EMRegAdd1(clk, reset, PipeClearEM, PipeEnableEM, AddSumE, AddSumM);
|
|
|
|
flopenrc #(64) EMRegAdd2(clk, reset, PipeClearEM, PipeEnableEM, AddSumTcE, AddSumTcM);
|
|
|
|
flopenrc #(4) EMRegAdd3(clk, reset, PipeClearEM, PipeEnableEM, AddSelInvE, AddSelInvM);
|
|
|
|
flopenrc #(11) EMRegAdd4(clk, reset, PipeClearEM, PipeEnableEM, AddExpPostSumE, AddExpPostSumM);
|
|
|
|
flopenrc #(1) EMRegAdd5(clk, reset, PipeClearEM, PipeEnableEM, AddCorrSignE, AddCorrSignM);
|
|
|
|
flopenrc #(1) EMRegAdd6(clk, reset, PipeClearEM, PipeEnableEM, AddOp1NormE, AddOp1NormM);
|
|
|
|
flopenrc #(1) EMRegAdd7(clk, reset, PipeClearEM, PipeEnableEM, AddOp2NormE, AddOp2NormM);
|
|
|
|
flopenrc #(1) EMRegAdd8(clk, reset, PipeClearEM, PipeEnableEM, AddOpANormE, AddOpANormM);
|
|
|
|
flopenrc #(1) EMRegAdd9(clk, reset, PipeClearEM, PipeEnableEM, AddOpBNormE, AddOpBNormM);
|
|
|
|
flopenrc #(1) EMRegAdd10(clk, reset, PipeClearEM, PipeEnableEM, AddInvalidE, AddInvalidM);
|
|
|
|
flopenrc #(1) EMRegAdd11(clk, reset, PipeClearEM, PipeEnableEM, AddDenormInE, AddDenormInM);
|
|
|
|
flopenrc #(1) EMRegAdd12(clk, reset, PipeClearEM, PipeEnableEM, AddConvertE, AddConvertM);
|
|
|
|
flopenrc #(1) EMRegAdd13(clk, reset, PipeClearEM, PipeEnableEM, AddSwapE, AddSwapM);
|
|
|
|
flopenrc #(1) EMRegAdd14(clk, reset, PipeClearEM, PipeEnableEM, AddNormOvflowE, AddNormOvflowM);
|
|
|
|
flopenrc #(1) EMRegAdd15(clk, reset, PipeClearEM, PipeEnableEM, AddSignAE, AddSignM);
|
|
|
|
flopenrc #(64) EMRegAdd16(clk, reset, PipeClearEM, PipeEnableEM, AddFloat1E, AddFloat1M);
|
|
|
|
flopenrc #(64) EMRegAdd17(clk, reset, PipeClearEM, PipeEnableEM, AddFloat2E, AddFloat2M);
|
|
|
|
flopenrc #(11) EMRegAdd18(clk, reset, PipeClearEM, PipeEnableEM, AddExp1DenormE, AddExp1DenormM);
|
|
|
|
flopenrc #(11) EMRegAdd19(clk, reset, PipeClearEM, PipeEnableEM, AddExp2DenormE, AddExp2DenormM);
|
|
|
|
flopenrc #(11) EMRegAdd20(clk, reset, PipeClearEM, PipeEnableEM, AddExponentE, AddExponentM);
|
|
|
|
flopenrc #(64) EMRegAdd21(clk, reset, PipeClearEM, PipeEnableEM, AddOp1E, AddOp1M);
|
|
|
|
flopenrc #(64) EMRegAdd22(clk, reset, PipeClearEM, PipeEnableEM, AddOp2E, AddOp2M);
|
|
|
|
flopenrc #(3) EMRegAdd23(clk, reset, PipeClearEM, PipeEnableEM, AddRmE, AddRmM);
|
|
|
|
flopenrc #(4) EMRegAdd24(clk, reset, PipeClearEM, PipeEnableEM, AddOpTypeE, AddOpTypeM);
|
|
|
|
flopenrc #(1) EMRegAdd25(clk, reset, PipeClearEM, PipeEnableEM, AddPE, AddPM);
|
|
|
|
flopenrc #(1) EMRegAdd26(clk, reset, PipeClearEM, PipeEnableEM, AddOvEnE, AddOvEnM);
|
|
|
|
flopenrc #(1) EMRegAdd27(clk, reset, PipeClearEM, PipeEnableEM, AddUnEnE, AddUnEnM);
|
|
|
|
|
|
|
|
//*****************
|
|
|
|
//fpcmp E/M pipe registers
|
|
|
|
//*****************
|
|
|
|
flopenrc #(8) EMRegCmp1(clk, reset, PipeClearEM, PipeEnableEM, WE, WM);
|
|
|
|
flopenrc #(8) EMRegCmp2(clk, reset, PipeClearEM, PipeEnableEM, XE, XM);
|
|
|
|
flopenrc #(1) EMRegcmp3(clk, reset, PipeClearEM, PipeEnableEM, ANaNE, ANaNM);
|
|
|
|
flopenrc #(1) EMRegCmp4(clk, reset, PipeClearEM, PipeEnableEM, BNaNE, BNaNM);
|
|
|
|
flopenrc #(1) EMRegCmp5(clk, reset, PipeClearEM, PipeEnableEM, AzeroE, AzeroM);
|
|
|
|
flopenrc #(1) EMRegCmp6(clk, reset, PipeClearEM, PipeEnableEM, BzeroE, BzeroM);
|
|
|
|
flopenrc #(64) EMRegCmp7(clk, reset, PipeClearEM, PipeEnableEM, CmpOp1E, CmpOp1M);
|
|
|
|
flopenrc #(64) EMRegCmp8(clk, reset, PipeClearEM, PipeEnableEM, CmpOp2E, CmpOp2M);
|
|
|
|
flopenrc #(2) EMRegCmp9(clk, reset, PipeClearEM, PipeEnableEM, CmpSelE, CmpSelM);
|
|
|
|
|
|
|
|
//put this in for the event we want to delay fsgn - will otherwise bypass
|
|
|
|
//*****************
|
|
|
|
//fpsgn E/M pipe registers
|
|
|
|
//*****************
|
|
|
|
flopenrc #(2) EMRegSgn1(clk, reset, PipeClearEM, PipeEnableEM, SgnOpCodeE, SgnOpCodeM);
|
|
|
|
flopenrc #(64) EMRegSgn2(clk, reset, PipeClearEM, PipeEnableEM, SgnResultE, SgnResultM);
|
|
|
|
flopenrc #(5) EMRegSgn3(clk, reset, PipeClearEM, PipeEnableEM, SgnFlagsE, SgnFlagsM);
|
|
|
|
|
|
|
|
//*****************
|
|
|
|
//other E/M pipe registers
|
|
|
|
//*****************
|
|
|
|
flopenrc #(1) EMReg1(clk, reset, PipeClearEM, PipeEnableEM, FRegWriteE, FRegWriteM);
|
|
|
|
flopenrc #(3) EMReg2(clk, reset, PipeClearEM, PipeEnableEM, FResultSelE, FResultSelM);
|
|
|
|
flopenrc #(3) EMReg3(clk, reset, PipeClearEM, PipeEnableEM, FrmE, FrmM);
|
|
|
|
flopenrc #(1) EMReg4(clk, reset, PipeClearEM, PipeEnableEM, PE, PM);
|
|
|
|
flopenrc #(4) EMReg5(clk, reset, PipeClearEM, PipeEnableEM, OpCtrlE, OpCtrlM);
|
|
|
|
|
|
|
|
//
|
|
|
|
//END E/M PIPE
|
|
|
|
//*****************************************
|
|
|
|
|
|
|
|
//#########################################
|
|
|
|
//BEGIN MEMORY STAGE
|
|
|
|
//
|
|
|
|
|
|
|
|
//fma2 ();
|
|
|
|
|
|
|
|
//second instance of two-stage floating-point add/cvt unit
|
|
|
|
fpuaddcvt2 fpadd2 (.*);
|
|
|
|
|
|
|
|
//second instance of two-stage floating-point comparator
|
|
|
|
fpucmp2 fpcmp2 (CmpInvalidM, CmpFCCM, ANaNM, BNaNM, AzeroM, BzeroM, WM, XM, CmpSelM, CmpOp1M, CmpOp2M);
|
|
|
|
|
|
|
|
//
|
|
|
|
//END MEMORY STAGE
|
|
|
|
//#########################################
|
|
|
|
|
|
|
|
|
|
|
|
//*****************************************
|
|
|
|
//BEGIN M/W PIPE
|
|
|
|
//
|
|
|
|
|
|
|
|
//wally-spec W stage control logic signal instantiation
|
|
|
|
logic FRegWriteW;
|
|
|
|
logic [2:0] FResultSelW;
|
|
|
|
logic PW;
|
|
|
|
|
|
|
|
//instantiate W stage fma signals here
|
|
|
|
|
|
|
|
//instantiation of W stage div/sqrt signals
|
|
|
|
logic DivDenormW;
|
|
|
|
logic [63:0] DivResultW;
|
|
|
|
logic [4:0] DivFlagsW;
|
|
|
|
|
|
|
|
//instantiation of W stage fsgn signals
|
|
|
|
logic [63:0] SgnResultW;
|
|
|
|
logic [4:0] SgnFlagsW;
|
|
|
|
|
|
|
|
//instantiation of W stage regfile signals
|
|
|
|
logic [`XLEN-1:0] ReadData1W, ReadData2W, ReadData3W;
|
|
|
|
logic [`XLEN-1:0] SrcAW;
|
|
|
|
|
|
|
|
//instantiation of W stage add/cvt signals
|
|
|
|
logic [63:0] AddResultW;
|
|
|
|
logic [4:0] AddFlagsW;
|
|
|
|
logic AddDenormW;
|
|
|
|
|
|
|
|
//instantiation of W stage cmp signals
|
|
|
|
logic CmpInvalidW;
|
|
|
|
logic [1:0] CmpFCCW;
|
|
|
|
|
|
|
|
//*****************
|
|
|
|
//fma M/W pipe registers
|
|
|
|
//*****************
|
|
|
|
|
|
|
|
//*****************
|
|
|
|
//fpdiv M/W pipe registers
|
|
|
|
//*****************
|
|
|
|
flopenrc #(64) MWRegDiv1(clk, reset, PipeClearMW, PipeEnableMW, DivResultM, DivResultW);
|
|
|
|
flopenrc #(5) MWRegDiv2(clk, reset, PipeClearMW, PipeEnableMW, DivFlagsM, DivFlagsW);
|
|
|
|
flopenrc #(1) MWRegDiv3(clk, reset, PipeClearMW, PipeEnableMW, DivDenormM, DivDenormW);
|
|
|
|
|
|
|
|
//*****************
|
|
|
|
//fpadd M/W pipe registers
|
|
|
|
//*****************
|
|
|
|
flopenrc #(64) MWRegAdd1(clk, reset, PipeClearMW, PipeEnableMW, AddResultM, AddResultW);
|
|
|
|
flopenrc #(5) MWRegAdd2(clk, reset, PipeClearMW, PipeEnableMW, AddFlagsM, AddFlagsW);
|
|
|
|
flopenrc #(1) MWRegAdd3(clk, reset, PipeClearMW, PipeEnableMW, AddDenormM, AddDenormW);
|
|
|
|
|
|
|
|
//*****************
|
|
|
|
//fpcmp M/W pipe registers
|
|
|
|
//*****************
|
|
|
|
flopenrc #(1) MWRegCmp1(clk, reset, PipeClearMW, PipeEnableMW, CmpInvalidM, CmpInvalidW);
|
|
|
|
flopenrc #(2) MWRegCmp2(clk, reset, PipeClearMW, PipeEnableMW, CmpFCCM, CmpFCCW);
|
|
|
|
|
|
|
|
//*****************
|
|
|
|
//fpsgn M/W pipe registers
|
|
|
|
//*****************
|
|
|
|
flopenrc #(64) MWRegSgn1(clk, reset, PipeClearMW, PipeEnableMW, SgnResultM, SgnResultW);
|
|
|
|
flopenrc #(5) MWRegSgn2(clk, reset, PipeClearMW, PipeEnableMW, SgnFlagsM, SgnFlagsW);
|
|
|
|
|
|
|
|
//*****************
|
|
|
|
//other M/W pipe registers
|
|
|
|
//*****************
|
|
|
|
flopenrc #(1) MWReg1(clk, reset, PipeClearMW, PipeEnableMW, FRegWriteM, FRegWriteW);
|
|
|
|
flopenrc #(3) MWReg2(clk, reset, PipeClearMW, PipeEnableMW, FResultSelM, FResultSelW);
|
|
|
|
flopenrc #(1) MWReg3(clk, reset, PipeClearMW, PipeEnableMW, PM, PW);
|
|
|
|
|
|
|
|
////END M/W PIPE
|
|
|
|
//*****************************************
|
|
|
|
|
|
|
|
|
|
|
|
//#########################################
|
|
|
|
//BEGIN WRITEBACK STAGE
|
|
|
|
//
|
|
|
|
|
|
|
|
//flag signal mux via in-line ternaries
|
|
|
|
logic [4:0] FPUFlagsW;
|
|
|
|
//if bit 2 is active set to sign flags - otherwise:
|
|
|
|
//iff bit one is high - if bit zero is active set to fma flags - otherwise
|
|
|
|
//set to cmp flags
|
|
|
|
//iff bit one is low - if bit zero is active set to add/cvt flags - otherwise
|
|
|
|
//set to div/sqrt flags
|
|
|
|
assign FPUFlagsW = (FResultSelW[2]) ? (SgnFlagsW) : (
|
|
|
|
(FResultSelW[1]) ?
|
|
|
|
( (FResultSelW[0]) ? (5'b00000) : ({CmpInvalidW,4'b0000}) )
|
|
|
|
: ( (FResultSelW[0]) ? (AddFlagsW) : (DivFlagsW) )
|
|
|
|
);
|
|
|
|
|
|
|
|
//result mux via in-line ternaries
|
|
|
|
logic [63:0] FPUResultDirW;
|
|
|
|
//the uses the same logic as for flag signals
|
|
|
|
assign FPUResultDirW = (FResultSelW[2]) ? (SgnResultW) : (
|
|
|
|
(FResultSelW[1]) ?
|
|
|
|
( (FResultSelW[0]) ? (64'b0) : ({62'b0,CmpFCCW}) )
|
|
|
|
: ( (FResultSelW[0]) ? (AddResultW) : (DivResultW) )
|
|
|
|
);
|
|
|
|
|
|
|
|
//interface between XLEN size datapath and double-precision sized
|
|
|
|
//floating-point results
|
|
|
|
//
|
|
|
|
//define offsets for LSB zero extension or truncation
|
|
|
|
always_comb begin
|
|
|
|
|
|
|
|
//zero extension
|
|
|
|
if(`XLEN > 64) begin
|
|
|
|
FPUResultW <= {FPUResultDirW,{XLENDIFF{1'b0}}};
|
|
|
|
end
|
|
|
|
//truncate
|
|
|
|
else begin
|
|
|
|
FPUResultW <= FPUResultDirW[63:64-`XLEN];
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
//
|
|
|
|
//END WRITEBACK STAGE
|
|
|
|
//#########################################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
endmodule
|