Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main

This commit is contained in:
Ross Thompson 2022-08-23 18:52:15 -05:00
commit e4cbb43c67
16 changed files with 154 additions and 150 deletions

View File

@ -41,23 +41,24 @@ module fctrl (
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
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 FRegWriteM, FRegWriteW, // FP register write enable
output logic [2:0] FrmM, // FP rounding mode output logic [2:0] FrmM, // FP rounding mode
output logic [`FMTBITS-1:0] FmtE, FmtM, // FP format output logic [`FMTBITS-1:0] FmtE, FmtM, // FP format
output logic DivStartE, // Start division or squareroot output logic DivStartE, // Start division or squareroot
output logic XEnE, YEnE, ZEnE, output logic XEnE, YEnE, ZEnE,
output logic YEnForwardE, ZEnForwardE, 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 [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] 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 [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 output logic [4:0] Adr1E, Adr2E, Adr3E // adresses of each input
); );
`define FCTRLW 11 `define FCTRLW 11
logic [`FCTRLW-1:0] ControlsD; logic [`FCTRLW-1:0] ControlsD;
logic IllegalFPUInstrE; logic IllegalFPUInstrD, IllegalFPUInstrE;
logic FRegWriteD; // FP register write enable logic FRegWriteD; // FP register write enable
logic DivStartD; // integer register write enable logic DivStartD; // integer register write enable
logic FWriteIntD; // 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 [1:0] FResSelD; // Select one of the results that finish in the memory stage
logic [2:0] FrmD, FrmE; // FP rounding mode logic [2:0] FrmD, FrmE; // FP rounding mode
logic [`FMTBITS-1:0] FmtD; // FP format 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 // 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 always_comb
if (STATUS_FS == 2'b00) // FPU instructions are illegal when FPU is disabled if (STATUS_FS == 2'b00) // FPU instructions are illegal when FPU is disabled
ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1; 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) else case(OpD)
// FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr // FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr
7'b0000111: case(Funct3D) 7'b0000111: case(Funct3D)
3'b010: ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0; // flw 3'b010: ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0; // flw
3'b011: ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0; // fld 3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b1_0_10_xx_0xx_0_0; // fld
default: ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1; // non-implemented instruction 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 endcase
7'b0100111: case(Funct3D) 7'b0100111: case(Funct3D)
3'b010: ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0; // fsw 3'b010: ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0; // fsw
3'b011: ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0; // fsd 3'b011: if (`D_SUPPORTED) ControlsD = `FCTRLW'b0_0_10_xx_0xx_0_0; // fsd
default: ControlsD = `FCTRLW'b0_0_00_xx_0xx_0_1; // non-implemented instruction 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 endcase
7'b1000011: ControlsD = `FCTRLW'b1_0_01_10_000_0_0; // fmadd 7'b1000011: ControlsD = `FCTRLW'b1_0_01_10_000_0_0; // fmadd
7'b1000111: ControlsD = `FCTRLW'b1_0_01_10_001_0_0; // fmsub 7'b1000111: ControlsD = `FCTRLW'b1_0_01_10_001_0_0; // fmsub
@ -239,23 +258,23 @@ module fctrl (
// 10 - xor sign // 10 - xor sign
// D/E pipleine register // D/E pipleine register
flopenrc #(12+`FMTBITS) DECtrlReg3(clk, reset, FlushE, ~StallE, flopenrc #(13+`FMTBITS) DECtrlReg3(clk, reset, FlushE, ~StallE,
{FRegWriteD, PostProcSelD, FResSelD, FrmD, FmtD, OpCtrlD, FWriteIntD}, {FRegWriteD, PostProcSelD, FResSelD, FrmD, FmtD, OpCtrlD, FWriteIntD, IllegalFPUInstrD},
{FRegWriteE, PostProcSelE, FResSelE, FrmE, FmtE, OpCtrlE, FWriteIntE}); {FRegWriteE, PostProcSelE, FResSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, IllegalFPUInstrE});
flopenrc #(15) DEAdrReg(clk, reset, FlushE, ~StallE, {InstrD[19:15], InstrD[24:20], InstrD[31:27]}, flopenrc #(15) DEAdrReg(clk, reset, FlushE, ~StallE, {InstrD[19:15], InstrD[24:20], InstrD[31:27]},
{Adr1E, Adr2E, Adr3E}); {Adr1E, Adr2E, Adr3E});
flopenrc #(1) DEDivStartReg(clk, reset, FlushE, ~StallE|FDivBusyE, DivStartD, DivStartE); flopenrc #(1) DEDivStartReg(clk, reset, FlushE, ~StallE|FDivBusyE, DivStartD, DivStartE);
if(`FLEN>`XLEN) assign FCvtIntE = (FResSelE == 2'b01);
flopenrc #(1) DEIllegalReg(clk, reset, FlushE, ~StallE, IllegalFPUInstrD, IllegalFPUInstrE);
// E/M pipleine register // E/M pipleine register
flopenrc #(12+int'(`FMTBITS)) EMCtrlReg (clk, reset, FlushM, ~StallM, flopenrc #(13+int'(`FMTBITS)) EMCtrlReg (clk, reset, FlushM, ~StallM,
{FRegWriteE, FResSelE, PostProcSelE, FrmE, FmtE, OpCtrlE, FWriteIntE}, {FRegWriteE, FResSelE, PostProcSelE, FrmE, FmtE, OpCtrlE, FWriteIntE, IllegalFPUInstrE},
{FRegWriteM, FResSelM, PostProcSelM, FrmM, FmtM, OpCtrlM, FWriteIntM}); {FRegWriteM, FResSelM, PostProcSelM, FrmM, FmtM, OpCtrlM, FWriteIntM, IllegalFPUInstrM});
if(`FLEN>`XLEN)
flopenrc #(1) EMIllegalReg(clk, reset, FlushM, ~StallM, IllegalFPUInstrE, IllegalFPUInstrM);
// M/W pipleine register // M/W pipleine register
flopenrc #(3) MWCtrlReg(clk, reset, FlushW, ~StallW, flopenrc #(3) MWCtrlReg(clk, reset, FlushW, ~StallW,
{FRegWriteM, FResSelM}, {FRegWriteM, FResSelM},
{FRegWriteW, FResSelW}); {FRegWriteW, FResSelW});
assign FCvtIntW = (FResSelW == 2'b01);
endmodule endmodule

View File

@ -50,7 +50,7 @@ module flags(
input logic [`NE+1:0] Me, // exponent of the normalized sum 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 [1:0] CvtNegResMsbs, // the negitive integer result's most significant bits
input logic FmaAs, FmaPs, // the product and modified Z signs 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 DivByZero,
output logic IntInvalid, Invalid, Overflow, // flags used to select the res output logic IntInvalid, Invalid, Overflow, // flags used to select the res
output logic [4:0] PostProcFlg // flags output logic [4:0] PostProcFlg // flags
@ -126,16 +126,16 @@ module flags(
// | | | | and if the result is not exact // | | | | and if the result is not exact
// | | | | | and if the input isnt infinity or NaN // | | | | | 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 // 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 // - 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 // if the res is too small to be represented and not 0
// | and if the res is not invalid (outside the integer bounds) // | 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 // select the inexact flag to output
assign Inexact = ToInt ? IntInexact : FpInexact; assign Inexact = ToInt ? IntInexact : FpInexact;

View File

@ -44,12 +44,13 @@ module fpu (
output logic FpLoadStoreM, // Fp load instruction? (to LSU) output logic FpLoadStoreM, // Fp load instruction? (to LSU)
output logic FStallD, // Stall the decode stage (To HZU) output logic FStallD, // Stall the decode stage (To HZU)
output logic FWriteIntE, // integer register write enable (to IEU) 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 [`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] 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 [`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 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) output logic [4:0] SetFflagsM // FPU flags (to privileged unit)
); );
@ -67,10 +68,9 @@ module fpu (
logic FWriteIntM; // Write to integer register logic FWriteIntM; // Write to integer register
logic [1:0] ForwardXE, ForwardYE, ForwardZE; // forwarding mux control signals logic [1:0] ForwardXE, ForwardYE, ForwardZE; // forwarding mux control signals
logic [2:0] OpCtrlE, OpCtrlM; // Select which opperation to do in each component 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 [1:0] PostProcSelE, PostProcSelM; // select result in the post processing unit
logic [4:0] Adr1E, Adr2E, Adr3E; // adresses of each input logic [4:0] Adr1E, Adr2E, Adr3E; // adresses of each input
logic IllegalFPUInstrM;
logic XEnE, YEnE, ZEnE; logic XEnE, YEnE, ZEnE;
logic YEnForwardE, ZEnForwardE; 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] 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] 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 [`FLEN-1:0] BoxedOneE; // Zero value for Z for multiplication, with NaN boxing if needed
// DECODE STAGE // DECODE STAGE
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -163,9 +163,9 @@ 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]), .InstrD, 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, .StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW, .FRM_REGW, .STATUS_FS, .FDivBusyE,
.reset, .clk, .IllegalFPUInstrD, .FRegWriteM, .FRegWriteW, .FrmM, .FmtE, .FmtM, .YEnForwardE, .ZEnForwardE, .reset, .clk, .FRegWriteM, .FRegWriteW, .FrmM, .FmtE, .FmtM, .YEnForwardE, .ZEnForwardE,
.DivStartE, .FWriteIntE, .FWriteIntM, .OpCtrlE, .OpCtrlM, .IllegalFPUInstrM, .XEnE, .YEnE, .ZEnE, .DivStartE, .FWriteIntE, .FCvtIntE, .FWriteIntM, .OpCtrlE, .OpCtrlM, .IllegalFPUInstrM, .XEnE, .YEnE, .ZEnE,
.FResSelE, .FResSelM, .FResSelW, .PostProcSelE, .PostProcSelM, .Adr1E, .Adr2E, .Adr3E); .FResSelE, .FResSelM, .FResSelW, .PostProcSelE, .PostProcSelM, .FCvtIntW, .Adr1E, .Adr2E, .Adr3E);
// FP register file // FP register file
fregfile fregfile (.clk, .reset, .we4(FRegWriteW), fregfile fregfile (.clk, .reset, .we4(FRegWriteW),

View File

@ -83,15 +83,13 @@ module postprocess (
logic [`NE+1:0] Me; logic [`NE+1:0] Me;
logic [`CORRSHIFTSZ-1:0] Mf; // corectly shifted fraction logic [`CORRSHIFTSZ-1:0] Mf; // corectly shifted fraction
logic [`NE+1:0] FullRe; // Re with bits to determine sign and overflow 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 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 [$clog2(`NORMSHIFTSZ)-1:0] ShiftAmt; // normalization shift count
logic [`NORMSHIFTSZ-1:0] ShiftIn; // is the sum zero logic [`NORMSHIFTSZ-1:0] ShiftIn; // is the sum zero
logic [`NORMSHIFTSZ-1:0] Shifted; // the shifted result logic [`NORMSHIFTSZ-1:0] Shifted; // the shifted result
logic Plus1; // add one to the final result? logic Plus1; // add one to the final result?
logic IntInvalid, Overflow, Invalid; // flags logic IntInvalid, Overflow, Invalid; // flags
logic UfL; logic G, R, S; // bits needed to determine rounding
logic [`FMTBITS-1:0] OutFmt; logic [`FMTBITS-1:0] OutFmt;
// fma signals // fma signals
logic [`NE+1:0] FmaMe; // exponent of the normalized sum 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, roundsign roundsign(.FmaPs, .FmaAs, .FmaInvA, .FmaOp, .DivOp, .CvtOp, .FmaNegSum,
.Sqrt, .FmaSs, .Xs, .Ys, .CvtCs, .Ms); .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, .Ms, .FmaMe, .FmaOp, .CvtOp, .CvtResDenormUf, .Mf, .ToInt, .CvtResUf,
.DivS, .DivDone, .DivS, .DivDone,
.DivOp, .UfPlus1, .FullRe, .Rf, .Re, .R, .UfL, .Me); .DivOp, .UfPlus1, .FullRe, .Rf, .Re, .S, .R, .G, .Me);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Sign calculation // 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); .FmaOp, .ZInf, .InfIn, .FmaSZero, .Mult, .Ms, .Ws);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -220,7 +218,7 @@ module postprocess (
flags flags(.XSNaN, .YSNaN, .ZSNaN, .XInf, .YInf, .ZInf, .InfIn, .XZero, .YZero, flags flags(.XSNaN, .YSNaN, .ZSNaN, .XInf, .YInf, .ZInf, .InfIn, .XZero, .YZero,
.Xs, .Sqrt, .ToInt, .IntToFp, .Int64, .Signed, .OutFmt, .CvtCe, .Xs, .Sqrt, .ToInt, .IntToFp, .Int64, .Signed, .OutFmt, .CvtCe,
.NaNIn, .FmaAs, .FmaPs, .R, .IntInvalid, .DivByZero, .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); .Me, .CvtNegResMsbs, .Invalid, .Overflow, .PostProcFlg);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -39,6 +39,7 @@ module resultsign(
input logic Mult, input logic Mult,
input logic R, input logic R,
input logic S, input logic S,
input logic G,
input logic Ms, input logic Ms,
output logic Ws output logic Ws
); );
@ -60,7 +61,7 @@ module resultsign(
// - if a multiply opperation is done, then use the products sign(Ps) // - 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 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 // - 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 // is the result negitive

View File

@ -60,16 +60,14 @@ module round(
output logic S, // sticky bit output logic S, // sticky bit
output logic [`NE+1:0] Me, output logic [`NE+1:0] Me,
output logic Plus1, 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 UfCalcPlus1;
logic NormS; // normalized sum's sticky bit logic NormS; // normalized sum's sticky bit
logic UfS; // sticky bit for underlow calculation
logic [`NF-1:0] RoundFrac; logic [`NF-1:0] RoundFrac;
logic FpRes, IntRes; logic FpRes, IntRes;
logic UfR; logic FpG, FpL, FpR;
logic FpRound, FpLSBRes, FpUfRound; logic L; // lsb of result
logic CalcPlus1, FpPlus1; logic CalcPlus1, FpPlus1;
logic [`FLEN:0] RoundAdd; // how much to add to the result 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 // only add the Addend sticky if doing an FMA opperation
// - the shifter shifts too far left when there's an underflow (shifting out all possible sticky bits) // - the shifter shifts too far left when there's an underflow (shifting out all possible sticky bits)
assign 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 // determine round and LSB of the rounded value
// - underflow round bit is used to determint the underflow flag // - underflow round bit is used to determint the underflow flag
if (`FPSIZES == 1) begin if (`FPSIZES == 1) begin
assign FpRound = Mf[`CORRSHIFTSZ-`NF-1]; assign FpG = Mf[`CORRSHIFTSZ-`NF-1];
assign FpLSBRes = Mf[`CORRSHIFTSZ-`NF]; assign FpL = Mf[`CORRSHIFTSZ-`NF];
assign FpUfRound = Mf[`CORRSHIFTSZ-`NF-2]; assign FpR = Mf[`CORRSHIFTSZ-`NF-2];
end else if (`FPSIZES == 2) begin end else if (`FPSIZES == 2) begin
assign FpRound = OutFmt ? Mf[`CORRSHIFTSZ-`NF-1] : Mf[`CORRSHIFTSZ-`NF1-1]; assign FpG = OutFmt ? Mf[`CORRSHIFTSZ-`NF-1] : Mf[`CORRSHIFTSZ-`NF1-1];
assign FpLSBRes = OutFmt ? Mf[`CORRSHIFTSZ-`NF] : Mf[`CORRSHIFTSZ-`NF1]; assign FpL = OutFmt ? Mf[`CORRSHIFTSZ-`NF] : Mf[`CORRSHIFTSZ-`NF1];
assign FpUfRound = OutFmt ? Mf[`CORRSHIFTSZ-`NF-2] : Mf[`CORRSHIFTSZ-`NF1-2]; assign FpR = OutFmt ? Mf[`CORRSHIFTSZ-`NF-2] : Mf[`CORRSHIFTSZ-`NF1-2];
end else if (`FPSIZES == 3) begin end else if (`FPSIZES == 3) begin
always_comb always_comb
case (OutFmt) case (OutFmt)
`FMT: begin `FMT: begin
FpRound = Mf[`CORRSHIFTSZ-`NF-1]; FpG = Mf[`CORRSHIFTSZ-`NF-1];
FpLSBRes = Mf[`CORRSHIFTSZ-`NF]; FpL = Mf[`CORRSHIFTSZ-`NF];
FpUfRound = Mf[`CORRSHIFTSZ-`NF-2]; FpR = Mf[`CORRSHIFTSZ-`NF-2];
end end
`FMT1: begin `FMT1: begin
FpRound = Mf[`CORRSHIFTSZ-`NF1-1]; FpG = Mf[`CORRSHIFTSZ-`NF1-1];
FpLSBRes = Mf[`CORRSHIFTSZ-`NF1]; FpL = Mf[`CORRSHIFTSZ-`NF1];
FpUfRound = Mf[`CORRSHIFTSZ-`NF1-2]; FpR = Mf[`CORRSHIFTSZ-`NF1-2];
end end
`FMT2: begin `FMT2: begin
FpRound = Mf[`CORRSHIFTSZ-`NF2-1]; FpG = Mf[`CORRSHIFTSZ-`NF2-1];
FpLSBRes = Mf[`CORRSHIFTSZ-`NF2]; FpL = Mf[`CORRSHIFTSZ-`NF2];
FpUfRound = Mf[`CORRSHIFTSZ-`NF2-2]; FpR = Mf[`CORRSHIFTSZ-`NF2-2];
end end
default: begin default: begin
FpRound = 1'bx; FpG = 1'bx;
FpLSBRes = 1'bx; FpL = 1'bx;
FpUfRound = 1'bx; FpR = 1'bx;
end end
endcase endcase
end else if (`FPSIZES == 4) begin end else if (`FPSIZES == 4) begin
always_comb always_comb
case (OutFmt) case (OutFmt)
2'h3: begin 2'h3: begin
FpRound = Mf[`CORRSHIFTSZ-`Q_NF-1]; FpG = Mf[`CORRSHIFTSZ-`Q_NF-1];
FpLSBRes = Mf[`CORRSHIFTSZ-`Q_NF]; FpL = Mf[`CORRSHIFTSZ-`Q_NF];
FpUfRound = Mf[`CORRSHIFTSZ-`Q_NF-2]; FpR = Mf[`CORRSHIFTSZ-`Q_NF-2];
end end
2'h1: begin 2'h1: begin
FpRound = Mf[`CORRSHIFTSZ-`D_NF-1]; FpG = Mf[`CORRSHIFTSZ-`D_NF-1];
FpLSBRes = Mf[`CORRSHIFTSZ-`D_NF]; FpL = Mf[`CORRSHIFTSZ-`D_NF];
FpUfRound = Mf[`CORRSHIFTSZ-`D_NF-2]; FpR = Mf[`CORRSHIFTSZ-`D_NF-2];
end end
2'h0: begin 2'h0: begin
FpRound = Mf[`CORRSHIFTSZ-`S_NF-1]; FpG = Mf[`CORRSHIFTSZ-`S_NF-1];
FpLSBRes = Mf[`CORRSHIFTSZ-`S_NF]; FpL = Mf[`CORRSHIFTSZ-`S_NF];
FpUfRound = Mf[`CORRSHIFTSZ-`S_NF-2]; FpR = Mf[`CORRSHIFTSZ-`S_NF-2];
end end
2'h2: begin 2'h2: begin
FpRound = Mf[`CORRSHIFTSZ-`H_NF-1]; FpG = Mf[`CORRSHIFTSZ-`H_NF-1];
FpLSBRes = Mf[`CORRSHIFTSZ-`H_NF]; FpL = Mf[`CORRSHIFTSZ-`H_NF];
FpUfRound = Mf[`CORRSHIFTSZ-`H_NF-2]; FpR = Mf[`CORRSHIFTSZ-`H_NF-2];
end end
endcase endcase
end end
assign R = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN-1] : FpRound; assign G = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN-1] : FpG;
assign L = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN] : FpLSBRes; assign L = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN] : FpL;
assign UfR = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN-2] : FpUfRound; assign R = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN-2] : FpR;
// used to determine underflow flag
assign UfL = FpRound;
// determine sticky
assign S = UfS | UfR;
always_comb begin always_comb begin
// Determine if you add 1 // Determine if you add 1
case (Frm) 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'b001: CalcPlus1 = 0;//round to zero
3'b010: CalcPlus1 = Ms;//round down 3'b010: CalcPlus1 = Ms;//round down
3'b011: CalcPlus1 = ~Ms;//round up 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; default: CalcPlus1 = 1'bx;
endcase endcase
// Determine if you add 1 (for underflow flag) // Determine if you add 1 (for underflow flag)
case (Frm) 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'b001: UfCalcPlus1 = 0;//round to zero
3'b010: UfCalcPlus1 = Ms;//round down 3'b010: UfCalcPlus1 = Ms;//round down
3'b011: UfCalcPlus1 = ~Ms;//round up 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; default: UfCalcPlus1 = 1'bx;
endcase endcase
end end
// If an answer is exact don't round // 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 FpPlus1 = Plus1&~(ToInt&CvtOp);
assign UfPlus1 = UfCalcPlus1 & S; // UfR is part of sticky assign UfPlus1 = UfCalcPlus1 & (S|R);
// Compute rounded result // Compute rounded result
if (`FPSIZES == 1) begin if (`FPSIZES == 1) begin

View File

@ -56,7 +56,7 @@ module srtfsm(
output logic DivDone, output logic DivDone,
output logic NegSticky, output logic NegSticky,
output logic DivBusy output logic DivBusy
); );
typedef enum logic [1:0] {IDLE, BUSY, DONE} statetype; typedef enum logic [1:0] {IDLE, BUSY, DONE} statetype;
statetype state; statetype state;
@ -69,15 +69,15 @@ module srtfsm(
assign DivBusy = (state == BUSY); assign DivBusy = (state == BUSY);
// calculate sticky bit // calculate sticky bit
// - there is a chance that a value is subtracted infinitly, resulting in an exact QM result // - 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 // radix-4 division can't create a QM that continually adds 0's
if (`RADIX == 2) begin if (`RADIX == 2) begin
logic [`DIVb+3:0] FZero, FSticky; logic [`DIVb+3:0] FZero, FSticky;
logic [`DIVb+3:0] LastK, FirstK; logic [`DIVb+2:0] LastK, FirstK;
assign LastK = ({4'b1111, LastC} & ~({4'b1111, LastC} << 1)); assign LastK = ({3'b111, LastC} & ~({3'b111, LastC} << 1));
assign FirstK = ({4'b1111, FirstC<<1} & ~({4'b1111, FirstC<<1} << 1)); assign FirstK = ({3'b111, FirstC<<1} & ~({3'b111, FirstC<<1} << 1));
assign FZero = SqrtM ? {{2{LastSM[`DIVb]}}, LastSM, 2'b0} | {LastK,1'b0} : {4'b1,D,{`DIVb-`DIVN+2{1'b0}}}; assign FZero = SqrtM ? {LastSM[`DIVb], LastSM, 2'b0} | {LastK,1'b0} : {3'b1,D,{`DIVb-`DIVN+2{1'b0}}};
assign FSticky = SqrtM ? {FirstSM, 2'b0} | {FirstK,1'b0} : {4'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 // *** |... 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 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 assign DivSE = |W&~((W+FSticky)==0); //***not efficent fix == and need the & qn

View File

@ -44,7 +44,6 @@ module datapath (
input logic ALUResultSrcE, input logic ALUResultSrcE,
input logic JumpE, input logic JumpE,
input logic BranchSignedE, input logic BranchSignedE,
input logic IllegalFPUInstrE,
input logic [`XLEN-1:0] PCE, input logic [`XLEN-1:0] PCE,
input logic [`XLEN-1:0] PCLinkE, input logic [`XLEN-1:0] PCLinkE,
output logic [1:0] FlagsE, 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 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 // Memory stage signals
input logic StallM, FlushM, input logic StallM, FlushM,
input logic FWriteIntM, input logic FWriteIntM, FCvtIntW,
input logic [`XLEN-1:0] FIntResM, input logic [`XLEN-1:0] FIntResM,
output logic [`XLEN-1:0] SrcAM, output logic [`XLEN-1:0] SrcAM,
output logic [`XLEN-1:0] WriteDataM, output logic [`XLEN-1:0] WriteDataM,
@ -62,7 +61,6 @@ module datapath (
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,
input logic [1:0] FResSelW,
input logic [`XLEN-1:0] ReadDataW, input logic [`XLEN-1:0] ReadDataW,
// input logic [`XLEN-1:0] PCLinkW, // input logic [`XLEN-1:0] PCLinkW,
input logic [`XLEN-1:0] CSRReadValW, MDUResultW, input logic [`XLEN-1:0] CSRReadValW, MDUResultW,
@ -87,8 +85,8 @@ module datapath (
// Writeback stage signals // Writeback stage signals
logic [`XLEN-1:0] SCResultW; logic [`XLEN-1:0] SCResultW;
logic [`XLEN-1:0] ResultW; logic [`XLEN-1:0] ResultW;
logic [`XLEN-1:0] IFResultW; logic [`XLEN-1:0] IFResultW, IFCvtResultW;
// Decode stage // Decode stage
assign Rs1D = InstrD[19:15]; assign Rs1D = InstrD[19:15];
assign Rs2D = InstrD[24:20]; assign Rs2D = InstrD[24:20];
@ -123,16 +121,14 @@ module datapath (
flopenrc #(`XLEN) IFResultWReg(clk, reset, FlushW, ~StallW, IFResultM, IFResultW); flopenrc #(`XLEN) IFResultWReg(clk, reset, FlushW, ~StallW, IFResultM, IFResultW);
flopenrc #(5) RdWReg(clk, reset, FlushW, ~StallW, RdM, RdW); 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 if (`F_SUPPORTED) begin:fpmux
logic [`XLEN-1:0] IFCvtResultW;
mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, IFResultM); mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, IFResultM);
mux2 #(`XLEN) cvtresultmuxW(IFResultW, FCvtIntResW, ~FResSelW[1]&FResSelW[0], IFCvtResultW); mux2 #(`XLEN) cvtresultmuxW(IFResultW, FCvtIntResW, FCvtIntW, IFCvtResultW);
mux5 #(`XLEN) resultmuxW(IFCvtResultW, ReadDataW, CSRReadValW, MDUResultW, SCResultW, ResultSrcW, ResultW);
end else begin:fpmux end else begin:fpmux
assign IFResultM = IEUResultM; assign IFResultM = IEUResultM; assign IFCvtResultW = IFResultW;
mux5 #(`XLEN) resultmuxW(IFResultW, ReadDataW, CSRReadValW, MDUResultW, SCResultW, ResultSrcW, ResultW);
end end
mux5 #(`XLEN) resultmuxW(IFCvtResultW, ReadDataW, CSRReadValW, MDUResultW, SCResultW, ResultSrcW, ResultW);
// handle Store Conditional result if atomic extension supported // handle Store Conditional result if atomic extension supported
if (`A_SUPPORTED) assign SCResultW = {{(`XLEN-1){1'b0}}, SquashSCW}; if (`A_SUPPORTED) assign SCResultW = {{(`XLEN-1){1'b0}}, SquashSCW};

View File

@ -35,7 +35,7 @@ module forward(
input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW, input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW,
input logic MemReadE, MDUE, CSRReadE, input logic MemReadE, MDUE, CSRReadE,
input logic RegWriteM, RegWriteW, input logic RegWriteM, RegWriteW,
input logic FWriteIntE, input logic FCvtIntE,
input logic SCE, input logic SCE,
// Forwarding controls // Forwarding controls
output logic [1:0] ForwardAE, ForwardBE, 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 // 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 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 LoadStallD = (MemReadE|SCE) & MatchDE;
assign MDUStallD = MDUE & MatchDE; assign MDUStallD = MDUE & MatchDE;
assign CSRRdStallD = CSRReadE & MatchDE; assign CSRRdStallD = CSRReadE & MatchDE;

View File

@ -39,8 +39,7 @@ module ieu (
// Execute Stage interface // Execute Stage interface
input logic [`XLEN-1:0] PCE, input logic [`XLEN-1:0] PCE,
input logic [`XLEN-1:0] PCLinkE, input logic [`XLEN-1:0] PCLinkE,
input logic FWriteIntE, input logic FWriteIntE, FCvtIntE, FCvtIntW,
input logic IllegalFPUInstrE,
output logic [`XLEN-1:0] IEUAdrE, output logic [`XLEN-1:0] IEUAdrE,
output logic MDUE, W64E, output logic MDUE, W64E,
output logic [2:0] Funct3E, output logic [2:0] Funct3E,
@ -60,7 +59,6 @@ module ieu (
// Writeback stage // Writeback stage
input logic [`XLEN-1:0] CSRReadValW, MDUResultW, input logic [`XLEN-1:0] CSRReadValW, MDUResultW,
input logic [1:0] FResSelW,
input logic [`XLEN-1:0] FCvtIntResW, input logic [`XLEN-1:0] FCvtIntResW,
output logic [4:0] RdW, output logic [4:0] RdW,
input logic [`XLEN-1:0] ReadDataW, input logic [`XLEN-1:0] ReadDataW,
@ -105,16 +103,16 @@ module ieu (
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, .IllegalFPUInstrE, .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, .FResSelW, .StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW,
.StallW, .FlushW, .RegWriteW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW, .StallW, .FlushW, .RegWriteW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW,
.CSRReadValW, .MDUResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW); .CSRReadValW, .MDUResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW);
forward fw( forward fw(
.Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW,
.MemReadE, .MDUE, .CSRReadE, .RegWriteM, .RegWriteW, .MemReadE, .MDUE, .CSRReadE, .RegWriteM, .RegWriteW,
.FWriteIntE, .SCE, .ForwardAE, .ForwardBE, .FCvtIntE, .SCE, .ForwardAE, .ForwardBE,
.FPUStallD, .LoadStallD, .MDUStallD, .CSRRdStallD); .FPUStallD, .LoadStallD, .MDUStallD, .CSRRdStallD);
endmodule endmodule

View File

@ -230,7 +230,7 @@ module lsu (
mux2 #(`LLEN) UnCachedDataMux(.d0(LittleEndianReadDataWordM), .d1({{`LLEN-`XLEN{1'b0}}, DLSUBusBuffer[`XLEN-1:0]}), mux2 #(`LLEN) UnCachedDataMux(.d0(LittleEndianReadDataWordM), .d1({{`LLEN-`XLEN{1'b0}}, DLSUBusBuffer[`XLEN-1:0]}),
.s(SelUncachedAdr), .y(ReadDataWordMuxM)); .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)); .s(SelUncachedAdr), .y(LSUBusHWDATA));
if(CACHE_ENABLED) begin : dcache if(CACHE_ENABLED) begin : dcache
cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN), cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN),

View File

@ -40,10 +40,10 @@ module subwordwrite (
if (`LLEN == 128) begin:sww if (`LLEN == 128) begin:sww
always_comb always_comb
case(LSUFunct3M[2:0]) case(LSUFunct3M[2:0])
2'b000: LittleEndianWriteDataM = {16{IMAFWriteDataM[7:0]}}; // sb 3'b000: LittleEndianWriteDataM = {16{IMAFWriteDataM[7:0]}}; // sb
2'b001: LittleEndianWriteDataM = {8{IMAFWriteDataM[15:0]}}; // sh 3'b001: LittleEndianWriteDataM = {8{IMAFWriteDataM[15:0]}}; // sh
2'b010: LittleEndianWriteDataM = {4{IMAFWriteDataM[31:0]}}; // sw 3'b010: LittleEndianWriteDataM = {4{IMAFWriteDataM[31:0]}}; // sw
2'b011: LittleEndianWriteDataM = {2{IMAFWriteDataM[63:0]}}; // sd 3'b011: LittleEndianWriteDataM = {2{IMAFWriteDataM[63:0]}}; // sd
default: LittleEndianWriteDataM = IMAFWriteDataM; // sq default: LittleEndianWriteDataM = IMAFWriteDataM; // sq
endcase endcase
end else if (`LLEN == 64) begin:sww end else if (`LLEN == 64) begin:sww

View File

@ -43,7 +43,7 @@ module privdec (
output logic EcallFaultM, BreakpointFaultM, output logic EcallFaultM, BreakpointFaultM,
output logic sretM, mretM, wfiM, sfencevmaM); output logic sretM, mretM, wfiM, sfencevmaM);
logic IllegalPrivilegedInstrM, IllegalOrDisabledFPUInstrM; logic IllegalPrivilegedInstrM;
logic WFITimeoutM; logic WFITimeoutM;
logic StallMQ; logic StallMQ;
logic ebreakM, ecallM; logic ebreakM, ecallM;
@ -92,7 +92,6 @@ module privdec (
// Fault on illegal instructions // Fault on illegal instructions
/////////////////////////////////////////// ///////////////////////////////////////////
assign IllegalPrivilegedInstrM = PrivilegedM & ~(sretM|mretM|ecallM|ebreakM|wfiM|sfencevmaM); assign IllegalPrivilegedInstrM = PrivilegedM & ~(sretM|mretM|ecallM|ebreakM|wfiM|sfencevmaM);
assign IllegalOrDisabledFPUInstrM = IllegalFPUInstrM | (STATUS_FS == 2'b00); assign IllegalInstrFaultM = (IllegalIEUInstrFaultM & IllegalFPUInstrM) | IllegalPrivilegedInstrM | IllegalCSRAccessM |
assign IllegalInstrFaultM = (IllegalIEUInstrFaultM & IllegalOrDisabledFPUInstrM) | IllegalPrivilegedInstrM | IllegalCSRAccessM |
WFITimeoutM; WFITimeoutM;
endmodule endmodule

View File

@ -52,7 +52,7 @@ module privileged (
input logic ICacheAccess, input logic ICacheAccess,
input logic PrivilegedM, input logic PrivilegedM,
input logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM, input logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM,
input logic InstrMisalignedFaultM, IllegalIEUInstrFaultD, IllegalFPUInstrD, input logic InstrMisalignedFaultM, IllegalIEUInstrFaultD, IllegalFPUInstrM,
input logic LoadMisalignedFaultM, input logic LoadMisalignedFaultM,
input logic StoreAmoMisalignedFaultM, input logic StoreAmoMisalignedFaultM,
input logic MTimerInt, MExtInt, SExtInt, MSwInt, input logic MTimerInt, MExtInt, SExtInt, MSwInt,
@ -69,7 +69,6 @@ module privileged (
input logic StoreAmoAccessFaultM, input logic StoreAmoAccessFaultM,
input logic SelHPTW, input logic SelHPTW,
output logic IllegalFPUInstrE,
output logic [1:0] PrivilegeModeW, output logic [1:0] PrivilegeModeW,
output logic [`XLEN-1:0] SATP_REGW, output logic [`XLEN-1:0] SATP_REGW,
output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
@ -88,7 +87,6 @@ module privileged (
logic sretM, mretM; logic sretM, mretM;
logic IllegalCSRAccessM; logic IllegalCSRAccessM;
logic IllegalIEUInstrFaultM; logic IllegalIEUInstrFaultM;
logic IllegalFPUInstrM;
logic InstrPageFaultM; logic InstrPageFaultM;
logic InstrAccessFaultM; logic InstrAccessFaultM;
logic IllegalInstrFaultM; logic IllegalInstrFaultM;
@ -148,9 +146,8 @@ module privileged (
.IllegalCSRAccessM, .BigEndianM); .IllegalCSRAccessM, .BigEndianM);
privpiperegs ppr(.clk, .reset, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM, privpiperegs ppr(.clk, .reset, .StallD, .StallE, .StallM, .FlushD, .FlushE, .FlushM,
.InstrPageFaultF, .InstrAccessFaultF, .IllegalIEUInstrFaultD, .IllegalFPUInstrD, .InstrPageFaultF, .InstrAccessFaultF, .IllegalIEUInstrFaultD,
.IllegalFPUInstrE, .InstrPageFaultM, .InstrAccessFaultM, .IllegalIEUInstrFaultM);
.InstrPageFaultM, .InstrAccessFaultM, .IllegalIEUInstrFaultM, .IllegalFPUInstrM);
trap trap(.reset, trap trap(.reset,
.InstrMisalignedFaultM, .InstrAccessFaultM, .IllegalInstrFaultM, .InstrMisalignedFaultM, .InstrAccessFaultM, .IllegalInstrFaultM,

View File

@ -35,10 +35,9 @@ module privpiperegs (
input logic StallD, StallE, StallM, input logic StallD, StallE, StallM,
input logic FlushD, FlushE, FlushM, input logic FlushD, FlushE, FlushM,
input logic InstrPageFaultF, InstrAccessFaultF, input logic InstrPageFaultF, InstrAccessFaultF,
input logic IllegalIEUInstrFaultD, IllegalFPUInstrD, input logic IllegalIEUInstrFaultD,
output logic IllegalFPUInstrE,
output logic InstrPageFaultM, InstrAccessFaultM, output logic InstrPageFaultM, InstrAccessFaultM,
output logic IllegalIEUInstrFaultM, IllegalFPUInstrM output logic IllegalIEUInstrFaultM
); );
logic InstrPageFaultD, InstrAccessFaultD; logic InstrPageFaultD, InstrAccessFaultD;
@ -49,10 +48,10 @@ module privpiperegs (
flopenrc #(2) faultregD(clk, reset, FlushD, ~StallD, flopenrc #(2) faultregD(clk, reset, FlushD, ~StallD,
{InstrPageFaultF, InstrAccessFaultF}, {InstrPageFaultF, InstrAccessFaultF},
{InstrPageFaultD, InstrAccessFaultD}); {InstrPageFaultD, InstrAccessFaultD});
flopenrc #(4) faultregE(clk, reset, FlushE, ~StallE, flopenrc #(3) faultregE(clk, reset, FlushE, ~StallE,
{IllegalIEUInstrFaultD, InstrPageFaultD, InstrAccessFaultD, IllegalFPUInstrD}, {IllegalIEUInstrFaultD, InstrPageFaultD, InstrAccessFaultD},
{IllegalIEUInstrFaultE, InstrPageFaultE, InstrAccessFaultE, IllegalFPUInstrE}); {IllegalIEUInstrFaultE, InstrPageFaultE, InstrAccessFaultE});
flopenrc #(4) faultregM(clk, reset, FlushM, ~StallM, flopenrc #(3) faultregM(clk, reset, FlushM, ~StallM,
{IllegalIEUInstrFaultE, InstrPageFaultE, InstrAccessFaultE, IllegalFPUInstrE}, {IllegalIEUInstrFaultE, InstrPageFaultE, InstrAccessFaultE},
{IllegalIEUInstrFaultM, InstrPageFaultM, InstrAccessFaultM, IllegalFPUInstrM}); {IllegalIEUInstrFaultM, InstrPageFaultM, InstrAccessFaultM});
endmodule endmodule

View File

@ -94,9 +94,10 @@ module wallypipelinedcore (
logic FWriteIntE; logic FWriteIntE;
logic [`FLEN-1:0] FWriteDataM; logic [`FLEN-1:0] FWriteDataM;
logic [`XLEN-1:0] FIntResM; logic [`XLEN-1:0] FIntResM;
logic [`XLEN-1:0] FCvtIntResW; logic [`XLEN-1:0] FCvtIntResW;
logic FCvtIntW;
logic FDivBusyE; logic FDivBusyE;
logic IllegalFPUInstrD, IllegalFPUInstrE; logic IllegalFPUInstrM;
logic FRegWriteM; logic FRegWriteM;
logic FPUStallD; logic FPUStallD;
logic FpLoadStoreM; logic FpLoadStoreM;
@ -170,6 +171,7 @@ module wallypipelinedcore (
logic BreakpointFaultM, EcallFaultM; logic BreakpointFaultM, EcallFaultM;
logic InstrDAPageFaultF; logic InstrDAPageFaultF;
logic BigEndianM; logic BigEndianM;
logic FCvtIntE;
ifu ifu( ifu ifu(
.clk, .reset, .clk, .reset,
@ -217,7 +219,7 @@ module wallypipelinedcore (
.IllegalBaseInstrFaultD, .IllegalBaseInstrFaultD,
// Execute Stage interface // Execute Stage interface
.PCE, .PCLinkE, .FWriteIntE, .IllegalFPUInstrE, .PCE, .PCLinkE, .FWriteIntE, .FCvtIntE,
.IEUAdrE, .MDUE, .W64E, .IEUAdrE, .MDUE, .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
@ -235,7 +237,7 @@ module wallypipelinedcore (
.RdW, .ReadDataW(ReadDataW[`XLEN-1:0]), .RdW, .ReadDataW(ReadDataW[`XLEN-1:0]),
.InstrValidM, .InstrValidM,
.FCvtIntResW, .FCvtIntResW,
.FResSelW, .FCvtIntW,
// hazards // hazards
.StallD, .StallE, .StallM, .StallW, .StallD, .StallE, .StallM, .StallW,
@ -344,7 +346,7 @@ module wallypipelinedcore (
.RASPredPCWrongM, .BPPredClassNonCFIWrongM, .RASPredPCWrongM, .BPPredClassNonCFIWrongM,
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .PrivilegedM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .PrivilegedM,
.InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM, .InstrPageFaultF, .LoadPageFaultM, .StoreAmoPageFaultM,
.InstrMisalignedFaultM, .IllegalIEUInstrFaultD, .IllegalFPUInstrD, .InstrMisalignedFaultM, .IllegalIEUInstrFaultD,
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
.MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTimerInt, .MExtInt, .SExtInt, .MSwInt,
.MTIME_CLINT, .MTIME_CLINT,
@ -354,7 +356,7 @@ module wallypipelinedcore (
// *** do these need to be split up into one for dmem and one for ifu? // *** 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? // 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, .InstrAccessFaultF, .LoadAccessFaultM, .StoreAmoAccessFaultM, .SelHPTW,
.IllegalFPUInstrE, .IllegalFPUInstrM,
.PrivilegeModeW, .SATP_REGW, .PrivilegeModeW, .SATP_REGW,
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .STATUS_FS,
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
@ -396,21 +398,23 @@ module wallypipelinedcore (
.FRegWriteM, // FP register write enable .FRegWriteM, // FP register write enable
.FpLoadStoreM, .FpLoadStoreM,
.FStallD, // Stall the decode stage .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 .FWriteDataM, // Data to be written to memory
.FIntResM, // data to be written to integer register .FIntResM, // data to be written to integer register
.FCvtIntResW, // fp -> int conversion result to be stored in int 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) .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) .SetFflagsM // FPU flags (to privileged unit)
); // floating point unit ); // floating point unit
end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low
assign FStallD = 0; assign FStallD = 0;
assign FWriteIntE = 0; assign FWriteIntE = 0;
assign FCvtIntE = 0;
assign FIntResM = 0; assign FIntResM = 0;
assign FCvtIntW = 0;
assign FDivBusyE = 0; assign FDivBusyE = 0;
assign IllegalFPUInstrD = 1; assign IllegalFPUInstrM = 1;
assign SetFflagsM = 0; assign SetFflagsM = 0;
end end
endmodule endmodule