mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Replaced MDUE with IntDivE in FDIVSQRT
This commit is contained in:
parent
f6987fab8c
commit
654abcde61
@ -68,7 +68,7 @@
|
|||||||
// Integer Divider Configuration
|
// Integer Divider Configuration
|
||||||
// IDIV_BITSPERCYCLE must be 1, 2, or 4
|
// IDIV_BITSPERCYCLE must be 1, 2, or 4
|
||||||
`define IDIV_BITSPERCYCLE 4
|
`define IDIV_BITSPERCYCLE 4
|
||||||
`define IDIV_ON_FPU 0
|
`define IDIV_ON_FPU 1
|
||||||
|
|
||||||
// Legal number of PMP entries are 0, 16, or 64
|
// Legal number of PMP entries are 0, 16, or 64
|
||||||
`define PMP_ENTRIES 16
|
`define PMP_ENTRIES 16
|
||||||
|
@ -69,7 +69,7 @@
|
|||||||
// Integer Divider Configuration
|
// Integer Divider Configuration
|
||||||
// IDIV_BITSPERCYCLE must be 1, 2, or 4
|
// IDIV_BITSPERCYCLE must be 1, 2, or 4
|
||||||
`define IDIV_BITSPERCYCLE 4
|
`define IDIV_BITSPERCYCLE 4
|
||||||
`define IDIV_ON_FPU 0
|
`define IDIV_ON_FPU 1
|
||||||
|
|
||||||
// Legal number of PMP entries are 0, 16, or 64
|
// Legal number of PMP entries are 0, 16, or 64
|
||||||
`define PMP_ENTRIES 16
|
`define PMP_ENTRIES 16
|
||||||
|
@ -35,7 +35,7 @@ module fctrl (
|
|||||||
input logic [6:0] OpD, // bits 6:0 of instruction
|
input logic [6:0] OpD, // bits 6:0 of instruction
|
||||||
input logic [4:0] Rs2D, // bits 24:20 of instruction
|
input logic [4:0] Rs2D, // bits 24:20 of instruction
|
||||||
input logic [2:0] Funct3D, Funct3E, // bits 14:12 of instruction - may contain rounding mode
|
input logic [2:0] Funct3D, Funct3E, // bits 14:12 of instruction - may contain rounding mode
|
||||||
input logic MDUE,
|
input logic IntDivE,
|
||||||
input logic [2:0] FRM_REGW, // rounding mode from CSR
|
input logic [2:0] FRM_REGW, // rounding mode from CSR
|
||||||
input logic [1:0] STATUS_FS, // is FPU enabled?
|
input logic [1:0] STATUS_FS, // is FPU enabled?
|
||||||
input logic FDivBusyE, // is the divider busy
|
input logic FDivBusyE, // is the divider busy
|
||||||
@ -270,7 +270,9 @@ module fctrl (
|
|||||||
flopenrc #(15) DEAdrReg(clk, reset, FlushE, ~StallE, {Adr1D, Adr2D, Adr3D}, {Adr1E, Adr2E, Adr3E});
|
flopenrc #(15) DEAdrReg(clk, reset, FlushE, ~StallE, {Adr1D, Adr2D, Adr3D}, {Adr1E, Adr2E, Adr3E});
|
||||||
flopenrc #(1) DEFDivStartReg(clk, reset, FlushE, ~StallE|FDivBusyE, FDivStartD, FDivStartE);
|
flopenrc #(1) DEFDivStartReg(clk, reset, FlushE, ~StallE|FDivBusyE, FDivStartD, FDivStartE);
|
||||||
flopenrc #(3) DEEnReg(clk, reset, FlushE, ~StallE, {XEnD, YEnD, ZEnD}, {XEnE, YEnE, ZEnE});
|
flopenrc #(3) DEEnReg(clk, reset, FlushE, ~StallE, {XEnD, YEnD, ZEnD}, {XEnE, YEnE, ZEnE});
|
||||||
if (`M_SUPPORTED) assign IDivStartE = MDUE & Funct3E[2];
|
|
||||||
|
// Integer division on FPU divider
|
||||||
|
if (`M_SUPPORTED & `IDIV_ON_FPU) assign IDivStartE = IntDivE;
|
||||||
else assign IDivStartE = 0;
|
else assign IDivStartE = 0;
|
||||||
|
|
||||||
//assign FCvtIntE = (FResSelE == 2'b01);
|
//assign FCvtIntE = (FResSelE == 2'b01);
|
||||||
|
@ -42,7 +42,7 @@ module fdivsqrt(
|
|||||||
input logic SqrtE, SqrtM,
|
input logic SqrtE, SqrtM,
|
||||||
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
||||||
input logic [2:0] Funct3E, Funct3M,
|
input logic [2:0] Funct3E, Funct3M,
|
||||||
input logic MDUE, W64E,
|
input logic IntDivE, W64E,
|
||||||
output logic DivSM,
|
output logic DivSM,
|
||||||
output logic FDivBusyE, IFDivStartE, FDivDoneE,
|
output logic FDivBusyE, IFDivStartE, FDivDoneE,
|
||||||
output logic [`NE+1:0] QeM,
|
output logic [`NE+1:0] QeM,
|
||||||
@ -65,7 +65,7 @@ module fdivsqrt(
|
|||||||
|
|
||||||
// Integer div/rem signals
|
// Integer div/rem signals
|
||||||
logic BZeroM; // Denominator is zero
|
logic BZeroM; // Denominator is zero
|
||||||
logic MDUM; // Integer operation
|
logic IntDivM; // Integer operation
|
||||||
logic [`DIVBLEN:0] nE, nM, mM; // Shift amounts
|
logic [`DIVBLEN:0] nE, nM, mM; // Shift amounts
|
||||||
logic NegQuotM, ALTBM, AsM, W64M; // Special handling for postprocessor
|
logic NegQuotM, ALTBM, AsM, W64M; // Special handling for postprocessor
|
||||||
logic [`XLEN-1:0] AM; // Original Numerator for postprocessor
|
logic [`XLEN-1:0] AM; // Original Numerator for postprocessor
|
||||||
@ -76,16 +76,16 @@ module fdivsqrt(
|
|||||||
.Fmt(FmtE), .Sqrt(SqrtE), .XZeroE, .Funct3E,
|
.Fmt(FmtE), .Sqrt(SqrtE), .XZeroE, .Funct3E,
|
||||||
.QeM, .X, .DPreproc,
|
.QeM, .X, .DPreproc,
|
||||||
// Int-specific
|
// Int-specific
|
||||||
.ForwardedSrcAE, .ForwardedSrcBE, .MDUE, .W64E, .ISpecialCaseE,
|
.ForwardedSrcAE, .ForwardedSrcBE, .IntDivE, .W64E, .ISpecialCaseE,
|
||||||
.nE, .BZeroM, .nM, .mM, .AM,
|
.nE, .BZeroM, .nM, .mM, .AM,
|
||||||
.MDUM, .W64M, .NegQuotM, .ALTBM, .AsM);
|
.IntDivM, .W64M, .NegQuotM, .ALTBM, .AsM);
|
||||||
|
|
||||||
fdivsqrtfsm fdivsqrtfsm( // FSM
|
fdivsqrtfsm fdivsqrtfsm( // FSM
|
||||||
.clk, .reset, .FmtE, .XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE,
|
.clk, .reset, .FmtE, .XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE,
|
||||||
.FDivStartE, .XsE, .SqrtE, .WZeroE, .FlushE, .StallM,
|
.FDivStartE, .XsE, .SqrtE, .WZeroE, .FlushE, .StallM,
|
||||||
.FDivBusyE, .IFDivStartE, .FDivDoneE, .SpecialCaseM,
|
.FDivBusyE, .IFDivStartE, .FDivDoneE, .SpecialCaseM,
|
||||||
// Int-specific
|
// Int-specific
|
||||||
.IDivStartE, .ISpecialCaseE, .nE, .MDUE);
|
.IDivStartE, .ISpecialCaseE, .nE, .IntDivE);
|
||||||
|
|
||||||
fdivsqrtiter fdivsqrtiter( // CSA Iterator
|
fdivsqrtiter fdivsqrtiter( // CSA Iterator
|
||||||
.clk, .IFDivStartE, .FDivBusyE, .SqrtE, .X, .DPreproc,
|
.clk, .IFDivStartE, .FDivBusyE, .SqrtE, .X, .DPreproc,
|
||||||
|
@ -39,7 +39,7 @@ module fdivsqrtfsm(
|
|||||||
input logic StallM,
|
input logic StallM,
|
||||||
input logic FlushE,
|
input logic FlushE,
|
||||||
input logic WZeroE,
|
input logic WZeroE,
|
||||||
input logic MDUE,
|
input logic IntDivE,
|
||||||
input logic [`DIVBLEN:0] nE,
|
input logic [`DIVBLEN:0] nE,
|
||||||
input logic ISpecialCaseE,
|
input logic ISpecialCaseE,
|
||||||
output logic IFDivStartE,
|
output logic IFDivStartE,
|
||||||
@ -61,7 +61,7 @@ module fdivsqrtfsm(
|
|||||||
|
|
||||||
// terminate immediately on special cases
|
// terminate immediately on special cases
|
||||||
assign FSpecialCaseE = XZeroE | (YZeroE&~SqrtE) | XInfE | YInfE | XNaNE | YNaNE | (XsE&SqrtE);
|
assign FSpecialCaseE = XZeroE | (YZeroE&~SqrtE) | XInfE | YInfE | XNaNE | YNaNE | (XsE&SqrtE);
|
||||||
if (`IDIV_ON_FPU) assign SpecialCaseE = MDUE ? ISpecialCaseE : FSpecialCaseE;
|
if (`IDIV_ON_FPU) assign SpecialCaseE = IntDivE ? ISpecialCaseE : FSpecialCaseE;
|
||||||
else assign SpecialCaseE = FSpecialCaseE;
|
else assign SpecialCaseE = FSpecialCaseE;
|
||||||
flopenr #(1) SpecialCaseReg(clk, reset, IFDivStartE, SpecialCaseE, SpecialCaseM); // save SpecialCase for checking in fdivsqrtpostproc
|
flopenr #(1) SpecialCaseReg(clk, reset, IFDivStartE, SpecialCaseE, SpecialCaseM); // save SpecialCase for checking in fdivsqrtpostproc
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ module fdivsqrtfsm(
|
|||||||
always_comb begin
|
always_comb begin
|
||||||
if (SqrtE) fbits = Nf + 2 + 2; // Nf + two fractional bits for round/guard + 2 for right shift by up to 2
|
if (SqrtE) fbits = Nf + 2 + 2; // Nf + two fractional bits for round/guard + 2 for right shift by up to 2
|
||||||
else fbits = Nf + 2 + `LOGR; // Nf + two fractional bits for round/guard + integer bits - try this when placing results in msbs
|
else fbits = Nf + 2 + `LOGR; // Nf + two fractional bits for round/guard + integer bits - try this when placing results in msbs
|
||||||
if (`IDIV_ON_FPU) cycles = MDUE ? ((nE + 1)/`DIVCOPIES) : (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES);
|
if (`IDIV_ON_FPU) cycles = IntDivE ? ((nE + 1)/`DIVCOPIES) : (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES);
|
||||||
else cycles = (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES);
|
else cycles = (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -40,10 +40,10 @@ module fdivsqrtpreproc (
|
|||||||
output logic [`DIVb-1:0] DPreproc,
|
output logic [`DIVb-1:0] DPreproc,
|
||||||
// Int-specific
|
// Int-specific
|
||||||
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
||||||
input logic MDUE, W64E,
|
input logic IntDivE, W64E,
|
||||||
output logic ISpecialCaseE,
|
output logic ISpecialCaseE,
|
||||||
output logic [`DIVBLEN:0] nE, nM, mM,
|
output logic [`DIVBLEN:0] nE, nM, mM,
|
||||||
output logic NegQuotM, ALTBM, MDUM, W64M,
|
output logic NegQuotM, ALTBM, IntDivM, W64M,
|
||||||
output logic AsM, BZeroM,
|
output logic AsM, BZeroM,
|
||||||
output logic [`XLEN-1:0] AM
|
output logic [`XLEN-1:0] AM
|
||||||
);
|
);
|
||||||
@ -91,8 +91,8 @@ module fdivsqrtpreproc (
|
|||||||
mux2 #(`XLEN) posbmux(BE, -BE, BsE, PosB);
|
mux2 #(`XLEN) posbmux(BE, -BE, BsE, PosB);
|
||||||
|
|
||||||
// Select integer or floating point inputs
|
// Select integer or floating point inputs
|
||||||
mux2 #(`DIVb) ifxmux({Xm, {(`DIVb-`NF-1){1'b0}}}, {PosA, {(`DIVb-`XLEN){1'b0}}}, MDUE, IFNormLenX);
|
mux2 #(`DIVb) ifxmux({Xm, {(`DIVb-`NF-1){1'b0}}}, {PosA, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFNormLenX);
|
||||||
mux2 #(`DIVb) ifdmux({Ym, {(`DIVb-`NF-1){1'b0}}}, {PosB, {(`DIVb-`XLEN){1'b0}}}, MDUE, IFNormLenD);
|
mux2 #(`DIVb) ifdmux({Ym, {(`DIVb-`NF-1){1'b0}}}, {PosB, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFNormLenD);
|
||||||
|
|
||||||
// calculate number of fractional bits p
|
// calculate number of fractional bits p
|
||||||
assign ZeroDiff = mE - ell; // Difference in number of leading zeros
|
assign ZeroDiff = mE - ell; // Difference in number of leading zeros
|
||||||
@ -122,11 +122,11 @@ module fdivsqrtpreproc (
|
|||||||
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
||||||
|
|
||||||
// Selet integer or floating-point operands
|
// Selet integer or floating-point operands
|
||||||
mux2 #(1) numzmux(XZeroE, AZeroE, MDUE, NumerZeroE);
|
mux2 #(1) numzmux(XZeroE, AZeroE, IntDivE, NumerZeroE);
|
||||||
mux2 #(`DIVb+4) xmux(PreShiftX, DivXShifted, MDUE, X);
|
mux2 #(`DIVb+4) xmux(PreShiftX, DivXShifted, IntDivE, X);
|
||||||
|
|
||||||
// pipeline registers
|
// pipeline registers
|
||||||
flopen #(1) mdureg(clk, IFDivStartE, MDUE, MDUM);
|
flopen #(1) mdureg(clk, IFDivStartE, IntDivE, IntDivM);
|
||||||
flopen #(1) w64reg(clk, IFDivStartE, W64E, W64M);
|
flopen #(1) w64reg(clk, IFDivStartE, W64E, W64M);
|
||||||
flopen #(1) altbreg(clk, IFDivStartE, ALTBE, ALTBM);
|
flopen #(1) altbreg(clk, IFDivStartE, ALTBE, ALTBM);
|
||||||
flopen #(1) negquotreg(clk, IFDivStartE, NegQuotE, NegQuotM);
|
flopen #(1) negquotreg(clk, IFDivStartE, NegQuotE, NegQuotM);
|
||||||
@ -151,8 +151,11 @@ module fdivsqrtpreproc (
|
|||||||
assign XPreproc = IFNormLenX << (ell + {{`DIVBLEN{1'b0}}, 1'b1});
|
assign XPreproc = IFNormLenX << (ell + {{`DIVBLEN{1'b0}}, 1'b1});
|
||||||
assign DPreproc = IFNormLenD << (mE + {{`DIVBLEN{1'b0}}, 1'b1});
|
assign DPreproc = IFNormLenD << (mE + {{`DIVBLEN{1'b0}}, 1'b1});
|
||||||
|
|
||||||
// append leading 1 (for nonzero inputs) and conditionally shift left by one to avoid sqrt(2)
|
// append leading 1 (for normal inputs)
|
||||||
mux2 #(`DIVb+1) sqrtxmux({~XZeroE, XPreproc}, {1'b0, ~XZeroE, XPreproc[`DIVb-1:1]}, (Xe[0]^ell[0]), PreSqrtX);
|
// shift square root to be in range [1/4, 1)
|
||||||
|
// 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.
|
||||||
|
mux2 #(`DIVb+1) sqrtxmux({~XZeroE, XPreproc}, {1'b0, ~XZeroE, XPreproc[`DIVb-1:1]}, (Xe[0] ^ ell[0]), PreSqrtX);
|
||||||
assign DivX = {3'b000, ~NumerZeroE, XPreproc};
|
assign DivX = {3'b000, ~NumerZeroE, XPreproc};
|
||||||
|
|
||||||
// Sqrt is initialized on step one as R(X-1), so depends on Radix
|
// Sqrt is initialized on step one as R(X-1), so depends on Radix
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
// fpu.sv
|
// fpu.sv
|
||||||
//
|
//
|
||||||
// Written: me@KatherineParry.com, James Stine, Brett Mathis
|
// Written: me@KatherineParry.com, James Stine, Brett Mathis, David Harris
|
||||||
// Modified: 6/23/2021
|
// Modified: 6/23/2021
|
||||||
//
|
//
|
||||||
// Purpose: FPU
|
// Purpose: Floating Point Unit Top-Level Interface
|
||||||
//
|
//
|
||||||
// A component of the Wally configurable RISC-V project.
|
// A component of the Wally configurable RISC-V project.
|
||||||
//
|
//
|
||||||
@ -37,8 +37,8 @@ module fpu (
|
|||||||
input logic FlushE, FlushM, FlushW, // flush signals (from HZU)
|
input logic FlushE, FlushM, FlushW, // flush signals (from HZU)
|
||||||
input logic [4:0] RdE, RdM, RdW, // which FP register to write to (from IEU)
|
input logic [4:0] RdE, RdM, RdW, // which FP register to write to (from IEU)
|
||||||
input logic [1:0] STATUS_FS, // Is floating-point enabled? (From privileged unit)
|
input logic [1:0] STATUS_FS, // Is floating-point enabled? (From privileged unit)
|
||||||
input logic [2:0] Funct3E, Funct3M,
|
input logic [2:0] Funct3E, Funct3M, // Funct fields of instruction specify type of operations
|
||||||
input logic MDUE, W64E,
|
input logic IntDivE, W64E, //
|
||||||
output logic FRegWriteM, // FP register write enable (to privileged unit)
|
output logic FRegWriteM, // FP register write enable (to privileged unit)
|
||||||
output logic FpLoadStoreM, // Fp load instruction? (to LSU)
|
output logic FpLoadStoreM, // Fp load instruction? (to LSU)
|
||||||
output logic FPUStallD, // Stall the decode stage (To HZU)
|
output logic FPUStallD, // Stall the decode stage (To HZU)
|
||||||
@ -161,7 +161,7 @@ module fpu (
|
|||||||
|
|
||||||
// calculate FP control signals
|
// calculate FP control signals
|
||||||
fctrl fctrl (.Funct7D(InstrD[31:25]), .OpD(InstrD[6:0]), .Rs2D(InstrD[24:20]), .Funct3D(InstrD[14:12]),
|
fctrl fctrl (.Funct7D(InstrD[31:25]), .OpD(InstrD[6:0]), .Rs2D(InstrD[24:20]), .Funct3D(InstrD[14:12]),
|
||||||
.Funct3E, .MDUE, .InstrD,
|
.Funct3E, .IntDivE, .InstrD,
|
||||||
.StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW, .FRM_REGW, .STATUS_FS, .FDivBusyE,
|
.StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW, .FRM_REGW, .STATUS_FS, .FDivBusyE,
|
||||||
.reset, .clk, .FRegWriteE, .FRegWriteM, .FRegWriteW, .FrmM, .FmtE, .FmtM,
|
.reset, .clk, .FRegWriteE, .FRegWriteM, .FRegWriteW, .FrmM, .FmtE, .FmtM,
|
||||||
.FDivStartE, .IDivStartE, .FWriteIntE, .FCvtIntE, .FWriteIntM, .OpCtrlE, .OpCtrlM, .IllegalFPUInstrM, .XEnD, .YEnD, .ZEnD, .XEnE, .YEnE, .ZEnE,
|
.FDivStartE, .IDivStartE, .FWriteIntE, .FCvtIntE, .FWriteIntM, .OpCtrlE, .OpCtrlM, .IllegalFPUInstrM, .XEnD, .YEnD, .ZEnD, .XEnE, .YEnE, .ZEnE,
|
||||||
@ -259,7 +259,7 @@ module fpu (
|
|||||||
// *** add other opperations
|
// *** add other opperations
|
||||||
fdivsqrt fdivsqrt(.clk, .reset, .FmtE, .XmE, .YmE, .XeE, .YeE, .SqrtE(OpCtrlE[0]), .SqrtM(OpCtrlM[0]),
|
fdivsqrt fdivsqrt(.clk, .reset, .FmtE, .XmE, .YmE, .XeE, .YeE, .SqrtE(OpCtrlE[0]), .SqrtM(OpCtrlM[0]),
|
||||||
.XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE, .FDivStartE, .IDivStartE, .XsE,
|
.XInfE, .YInfE, .XZeroE, .YZeroE, .XNaNE, .YNaNE, .FDivStartE, .IDivStartE, .XsE,
|
||||||
.ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .Funct3M, .MDUE, .W64E,
|
.ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .Funct3M, .IntDivE, .W64E,
|
||||||
.StallM, .FlushE, .DivSM, .FDivBusyE, .IFDivStartE, .FDivDoneE, .QeM,
|
.StallM, .FlushE, .DivSM, .FDivBusyE, .IFDivStartE, .FDivDoneE, .QeM,
|
||||||
.QmM, .FPIntDivResultM /*, .DivDone(DivDoneM) */);
|
.QmM, .FPIntDivResultM /*, .DivDone(DivDoneM) */);
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ module controller(
|
|||||||
output logic ALUResultSrcE,
|
output logic ALUResultSrcE,
|
||||||
output logic MemReadE, CSRReadE, // for Hazard Unit
|
output logic MemReadE, CSRReadE, // for Hazard Unit
|
||||||
output logic [2:0] Funct3E,
|
output logic [2:0] Funct3E,
|
||||||
output logic MDUE, W64E,
|
output logic IntDivE, MDUE, W64E,
|
||||||
output logic JumpE,
|
output logic JumpE,
|
||||||
output logic SCE,
|
output logic SCE,
|
||||||
output logic BranchSignedE,
|
output logic BranchSignedE,
|
||||||
@ -61,7 +61,7 @@ module controller(
|
|||||||
output logic FWriteIntM,
|
output logic FWriteIntM,
|
||||||
// Writeback stage control signals
|
// Writeback stage control signals
|
||||||
input logic StallW, FlushW,
|
input logic StallW, FlushW,
|
||||||
output logic RegWriteW, DivW, // for datapath and Hazard Unit
|
output logic RegWriteW, IntDivW, // for datapath and Hazard Unit
|
||||||
output logic [2:0] ResultSrcW,
|
output logic [2:0] ResultSrcW,
|
||||||
// Stall during CSRs
|
// Stall during CSRs
|
||||||
//output logic CSRWriteFencePendingDEM,
|
//output logic CSRWriteFencePendingDEM,
|
||||||
@ -107,7 +107,7 @@ module controller(
|
|||||||
logic [1:0] AtomicE;
|
logic [1:0] AtomicE;
|
||||||
logic FenceD, FenceE, FenceM;
|
logic FenceD, FenceE, FenceM;
|
||||||
logic SFenceVmaD;
|
logic SFenceVmaD;
|
||||||
logic DivE, DivM;
|
logic IntDivM;
|
||||||
|
|
||||||
|
|
||||||
// Extract fields
|
// Extract fields
|
||||||
@ -227,17 +227,17 @@ module controller(
|
|||||||
assign MemReadE = MemRWE[1];
|
assign MemReadE = MemRWE[1];
|
||||||
assign SCE = (ResultSrcE == 3'b100);
|
assign SCE = (ResultSrcE == 3'b100);
|
||||||
assign RegWriteE = IEURegWriteE | FWriteIntE; // IRF register writes could come from IEU or FPU controllers
|
assign RegWriteE = IEURegWriteE | FWriteIntE; // IRF register writes could come from IEU or FPU controllers
|
||||||
assign DivE = MDUE & Funct3E[2]; // Division operation
|
assign IntDivE = MDUE & Funct3E[2]; // Integer division operation
|
||||||
|
|
||||||
// Memory stage pipeline control register
|
// Memory stage pipeline control register
|
||||||
flopenrc #(20) controlregM(clk, reset, FlushM, ~StallM,
|
flopenrc #(20) controlregM(clk, reset, FlushM, ~StallM,
|
||||||
{RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE, DivE},
|
{RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE, IntDivE},
|
||||||
{RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, FenceM, InstrValidM, DivM});
|
{RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, FenceM, InstrValidM, IntDivM});
|
||||||
|
|
||||||
// Writeback stage pipeline control register
|
// Writeback stage pipeline control register
|
||||||
flopenrc #(5) controlregW(clk, reset, FlushW, ~StallW,
|
flopenrc #(5) controlregW(clk, reset, FlushW, ~StallW,
|
||||||
{RegWriteM, ResultSrcM, DivM},
|
{RegWriteM, ResultSrcM, IntDivM},
|
||||||
{RegWriteW, ResultSrcW, DivW});
|
{RegWriteW, ResultSrcW, IntDivW});
|
||||||
|
|
||||||
// Flush F, D, and E stages on a CSR write or Fence.I or SFence.VMA
|
// Flush F, D, and E stages on a CSR write or Fence.I or SFence.VMA
|
||||||
assign CSRWriteFenceM = CSRWriteM | FenceM;
|
assign CSRWriteFenceM = CSRWriteM | FenceM;
|
||||||
|
@ -53,7 +53,7 @@ module datapath (
|
|||||||
output logic [`XLEN-1:0] WriteDataM,
|
output logic [`XLEN-1:0] WriteDataM,
|
||||||
// Writeback stage signals
|
// Writeback stage signals
|
||||||
input logic StallW, FlushW,
|
input logic StallW, FlushW,
|
||||||
(* mark_debug = "true" *) input logic RegWriteW, DivW,
|
(* mark_debug = "true" *) input logic RegWriteW, IntDivW,
|
||||||
input logic SquashSCW,
|
input logic SquashSCW,
|
||||||
input logic [2:0] ResultSrcW,
|
input logic [2:0] ResultSrcW,
|
||||||
input logic [`XLEN-1:0] FCvtIntResW,
|
input logic [`XLEN-1:0] FCvtIntResW,
|
||||||
@ -122,7 +122,7 @@ module datapath (
|
|||||||
mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, IFResultM);
|
mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, IFResultM);
|
||||||
mux2 #(`XLEN) cvtresultmuxW(IFResultW, FCvtIntResW, FCvtIntW, IFCvtResultW);
|
mux2 #(`XLEN) cvtresultmuxW(IFResultW, FCvtIntResW, FCvtIntW, IFCvtResultW);
|
||||||
if (`IDIV_ON_FPU) begin
|
if (`IDIV_ON_FPU) begin
|
||||||
mux2 #(`XLEN) divresultmuxW(MDUResultW, FPIntDivResultW, DivW, MulDivResultW);
|
mux2 #(`XLEN) divresultmuxW(MDUResultW, FPIntDivResultW, IntDivW, MulDivResultW);
|
||||||
end else begin
|
end else begin
|
||||||
assign MulDivResultW = MDUResultW;
|
assign MulDivResultW = MDUResultW;
|
||||||
end
|
end
|
||||||
|
@ -37,7 +37,7 @@ module ieu (
|
|||||||
input logic [`XLEN-1:0] PCLinkE,
|
input logic [`XLEN-1:0] PCLinkE,
|
||||||
input logic FWriteIntE, FCvtIntE, FCvtIntW,
|
input logic FWriteIntE, FCvtIntE, FCvtIntW,
|
||||||
output logic [`XLEN-1:0] IEUAdrE,
|
output logic [`XLEN-1:0] IEUAdrE,
|
||||||
output logic MDUE, W64E,
|
output logic IntDivE, W64E,
|
||||||
output logic [2:0] Funct3E,
|
output logic [2:0] Funct3E,
|
||||||
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
|
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
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ module ieu (
|
|||||||
logic ALUResultSrcE;
|
logic ALUResultSrcE;
|
||||||
logic SCE;
|
logic SCE;
|
||||||
logic FWriteIntM;
|
logic FWriteIntM;
|
||||||
logic DivW;
|
logic IntDivW;
|
||||||
|
|
||||||
// forwarding signals
|
// forwarding signals
|
||||||
logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E;
|
logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E;
|
||||||
@ -87,22 +87,23 @@ module ieu (
|
|||||||
logic MemReadE, CSRReadE;
|
logic MemReadE, CSRReadE;
|
||||||
logic JumpE;
|
logic JumpE;
|
||||||
logic BranchSignedE;
|
logic BranchSignedE;
|
||||||
|
logic MDUE;
|
||||||
|
|
||||||
controller c(
|
controller c(
|
||||||
.clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD,
|
.clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD,
|
||||||
.IllegalIEUInstrFaultD, .IllegalBaseInstrFaultD, .StallE, .FlushE, .FlagsE, .FWriteIntE,
|
.IllegalIEUInstrFaultD, .IllegalBaseInstrFaultD, .StallE, .FlushE, .FlagsE, .FWriteIntE,
|
||||||
.PCSrcE, .ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .MemReadE, .CSRReadE,
|
.PCSrcE, .ALUControlE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .MemReadE, .CSRReadE,
|
||||||
.Funct3E, .MDUE, .W64E, .JumpE, .SCE, .BranchSignedE, .StallM, .FlushM, .MemRWM,
|
.Funct3E, .IntDivE, .MDUE, .W64E, .JumpE, .SCE, .BranchSignedE, .StallM, .FlushM, .MemRWM,
|
||||||
.CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
|
.CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
|
||||||
.RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .FWriteIntM,
|
.RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .FWriteIntM,
|
||||||
.StallW, .FlushW, .RegWriteW, .DivW, .ResultSrcW, .CSRWriteFenceM, .StoreStallD);
|
.StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .StoreStallD);
|
||||||
|
|
||||||
datapath dp(
|
datapath dp(
|
||||||
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE,
|
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE,
|
||||||
.ALUControlE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .JumpE, .BranchSignedE,
|
.ALUControlE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .JumpE, .BranchSignedE,
|
||||||
.PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE,
|
.PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE,
|
||||||
.StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW,
|
.StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW,
|
||||||
.StallW, .FlushW, .RegWriteW, .DivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW,
|
.StallW, .FlushW, .RegWriteW, .IntDivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW,
|
||||||
.CSRReadValW, .MDUResultW, .FPIntDivResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW);
|
.CSRReadValW, .MDUResultW, .FPIntDivResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW);
|
||||||
|
|
||||||
forward fw(
|
forward fw(
|
||||||
|
@ -34,7 +34,7 @@ module intdivrestoring (
|
|||||||
input logic StallM,
|
input logic StallM,
|
||||||
input logic FlushE,
|
input logic FlushE,
|
||||||
input logic DivSignedE, W64E,
|
input logic DivSignedE, W64E,
|
||||||
input logic DivE,
|
input logic IntDivE,
|
||||||
//input logic [`XLEN-1:0] SrcAE, SrcBE,
|
//input logic [`XLEN-1:0] SrcAE, SrcBE,
|
||||||
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
||||||
output logic DivBusyE,
|
output logic DivBusyE,
|
||||||
@ -58,7 +58,7 @@ module intdivrestoring (
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
|
|
||||||
// Divider control signals
|
// Divider control signals
|
||||||
assign DivStartE = DivE & (state == IDLE) & ~StallM;
|
assign DivStartE = IntDivE & (state == IDLE) & ~StallM;
|
||||||
assign DivBusyE = (state == BUSY) | DivStartE;
|
assign DivBusyE = (state == BUSY) | DivStartE;
|
||||||
|
|
||||||
// Handle sign extension for W-type instructions
|
// Handle sign extension for W-type instructions
|
||||||
|
@ -32,7 +32,7 @@ module mdu (
|
|||||||
// input logic [`XLEN-1:0] SrcAE, SrcBE,
|
// input logic [`XLEN-1:0] SrcAE, SrcBE,
|
||||||
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
||||||
input logic [2:0] Funct3E, Funct3M,
|
input logic [2:0] Funct3E, Funct3M,
|
||||||
input logic MDUE, W64E,
|
input logic IntDivE, W64E,
|
||||||
// Writeback stage
|
// Writeback stage
|
||||||
output logic [`XLEN-1:0] MDUResultW,
|
output logic [`XLEN-1:0] MDUResultW,
|
||||||
// Divide Done
|
// Divide Done
|
||||||
@ -47,7 +47,6 @@ module mdu (
|
|||||||
logic [`XLEN*2-1:0] ProdM;
|
logic [`XLEN*2-1:0] ProdM;
|
||||||
|
|
||||||
logic DivSignedE;
|
logic DivSignedE;
|
||||||
logic DivE;
|
|
||||||
logic W64M;
|
logic W64M;
|
||||||
|
|
||||||
// Multiplier
|
// Multiplier
|
||||||
@ -61,9 +60,8 @@ module mdu (
|
|||||||
assign RemM = 0;
|
assign RemM = 0;
|
||||||
assign DivBusyE = 0;
|
assign DivBusyE = 0;
|
||||||
end else begin
|
end else begin
|
||||||
assign DivE = MDUE & Funct3E[2];
|
|
||||||
assign DivSignedE = ~Funct3E[0];
|
assign DivSignedE = ~Funct3E[0];
|
||||||
intdivrestoring div(.clk, .reset, .StallM, .FlushE, .DivSignedE, .W64E, .DivE,
|
intdivrestoring div(.clk, .reset, .StallM, .FlushE, .DivSignedE, .W64E, .IntDivE,
|
||||||
.ForwardedSrcAE, .ForwardedSrcBE, .DivBusyE, .QuotM, .RemM);
|
.ForwardedSrcAE, .ForwardedSrcBE, .DivBusyE, .QuotM, .RemM);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ module wallypipelinedcore (
|
|||||||
(* mark_debug = "true" *) logic TrapM;
|
(* mark_debug = "true" *) logic TrapM;
|
||||||
|
|
||||||
// new signals that must connect through DP
|
// new signals that must connect through DP
|
||||||
logic MDUE, W64E;
|
logic IntDivE, W64E;
|
||||||
logic CSRReadM, CSRWriteM, PrivilegedM;
|
logic CSRReadM, CSRWriteM, PrivilegedM;
|
||||||
logic [1:0] AtomicM;
|
logic [1:0] AtomicM;
|
||||||
logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; //, SrcAE, SrcBE;
|
logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; //, SrcAE, SrcBE;
|
||||||
@ -210,7 +210,7 @@ module wallypipelinedcore (
|
|||||||
|
|
||||||
// Execute Stage interface
|
// Execute Stage interface
|
||||||
.PCE, .PCLinkE, .FWriteIntE, .FCvtIntE,
|
.PCE, .PCLinkE, .FWriteIntE, .FCvtIntE,
|
||||||
.IEUAdrE, .MDUE, .W64E,
|
.IEUAdrE, .IntDivE, .W64E,
|
||||||
.Funct3E, .ForwardedSrcAE, .ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
.Funct3E, .ForwardedSrcAE, .ForwardedSrcBE, // *** these are the src outputs before the mux choosing between them and PCE to put in srcA/B
|
||||||
|
|
||||||
// Memory stage interface
|
// Memory stage interface
|
||||||
@ -367,7 +367,7 @@ module wallypipelinedcore (
|
|||||||
mdu mdu(
|
mdu mdu(
|
||||||
.clk, .reset,
|
.clk, .reset,
|
||||||
.ForwardedSrcAE, .ForwardedSrcBE,
|
.ForwardedSrcAE, .ForwardedSrcBE,
|
||||||
.Funct3E, .Funct3M, .MDUE, .W64E,
|
.Funct3E, .Funct3M, .IntDivE, .W64E,
|
||||||
.MDUResultW, .DivBusyE,
|
.MDUResultW, .DivBusyE,
|
||||||
.StallM, .StallW, .FlushE, .FlushM, .FlushW
|
.StallM, .StallW, .FlushE, .FlushM, .FlushW
|
||||||
);
|
);
|
||||||
@ -391,7 +391,7 @@ module wallypipelinedcore (
|
|||||||
.FRegWriteM, // FP register write enable
|
.FRegWriteM, // FP register write enable
|
||||||
.FpLoadStoreM,
|
.FpLoadStoreM,
|
||||||
.ForwardedSrcBE, // Integer input for intdiv
|
.ForwardedSrcBE, // Integer input for intdiv
|
||||||
.Funct3E, .Funct3M, .MDUE, .W64E, // Integer flags and functions
|
.Funct3E, .Funct3M, .IntDivE, .W64E, // Integer flags and functions
|
||||||
.FPUStallD, // Stall the decode stage
|
.FPUStallD, // Stall the decode stage
|
||||||
.FWriteIntE, .FCvtIntE, // integer register write enable, conversion operation
|
.FWriteIntE, .FCvtIntE, // integer register write enable, conversion operation
|
||||||
.FWriteDataM, // Data to be written to memory
|
.FWriteDataM, // Data to be written to memory
|
||||||
|
Loading…
Reference in New Issue
Block a user