Simplified FPU-LSU interface to skip IEU

This commit is contained in:
David Harris 2022-08-22 13:28:51 -07:00
parent 2e20b3ed72
commit d556adde16
3 changed files with 19 additions and 29 deletions

View File

@ -42,10 +42,9 @@ module fpu (
input logic [1:0] STATUS_FS, // Is floating-point enabled? (From privileged unit)
output logic FRegWriteM, // FP register write enable (to privileged unit)
output logic FpLoadStoreM, // Fp load instruction? (to LSU)
output logic FStore2, // store two words into memory (to LSU)
output logic FStallD, // Stall the decode stage (To HZU)
output logic FWriteIntE, // integer register write enable (to IEU)
output logic [`XLEN-1:0] FWriteDataE, // Data to be written to memory (to IEU) - only used if `XLEN >`FLEN
output logic [`XLEN-1:0] FWriteDataE, // Data to be written to memory (to IEU) - only used if `XLEN >`FLEN *** delete this
output logic [`FLEN-1:0] FWriteDataM, // Data to be written to memory (to IEU) - only used if `XLEN <`FLEN
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)
@ -290,22 +289,18 @@ module fpu (
// - FP uses NaN-blocking format
// - if there are any unsused bits the most significant bits are filled with 1s
if(`LLEN==`XLEN)
assign FWriteDataE = {{`XLEN-`FLEN{1'b1}}, YE};
else begin
logic [`FLEN-1:0] WriteDataE;
if(`FPSIZES == 1) assign WriteDataE = YE;
else if(`FPSIZES == 2) assign WriteDataE = FmtE ? YE : {`FLEN/`LEN1{YE[`LEN1-1:0]}};
else
always_comb
case(FmtE)
`Q_FMT: WriteDataE = YE;
`D_FMT: WriteDataE = {`FLEN/`D_LEN{YE[`D_LEN-1:0]}};
`S_FMT: WriteDataE = {`FLEN/`S_LEN{YE[`S_LEN-1:0]}};
`H_FMT: WriteDataE = {`FLEN/`H_LEN{YE[`H_LEN-1:0]}};
endcase
flopenrc #(`FLEN) EMWriteDataReg (clk, reset, FlushM, ~StallM, WriteDataE, FWriteDataM);
end
logic [`FLEN-1:0] WriteDataE;
if(`FPSIZES == 1) assign WriteDataE = YE;
else if(`FPSIZES == 2) assign WriteDataE = FmtE ? YE : {`FLEN/`LEN1{YE[`LEN1-1:0]}};
else
always_comb
case(FmtE)
`Q_FMT: WriteDataE = YE;
`D_FMT: WriteDataE = {`FLEN/`D_LEN{YE[`D_LEN-1:0]}};
`S_FMT: WriteDataE = {`FLEN/`S_LEN{YE[`S_LEN-1:0]}};
`H_FMT: WriteDataE = {`FLEN/`H_LEN{YE[`H_LEN-1:0]}};
endcase
flopenrc #(`FLEN) EMWriteDataReg (clk, reset, FlushM, ~StallM, WriteDataE, FWriteDataM);
// NaN Block SrcA
generate

View File

@ -64,8 +64,10 @@ module hazard(
assign StallFCause = CSRWriteFencePendingDEM & ~(TrapM | RetM | BPPredWrongE);
// stall in decode if instruction is a load/mul/csr dependent on previous
assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FPUStallD | FStallD) & ~(TrapM | RetM | BPPredWrongE);
// assign StallECause = (DivBusyE | FDivBusyE) & ~(TrapM); // *** can we move to decode stage (KP?)
assign StallECause = (DivBusyE) & ~(TrapM); // *** can we move to decode stage (KP?)
// WFI terminates if any enabled interrupt is pending, even if global interrupts are disabled. It could also terminate with TW trap
// assign StallMCause = (wfiM & (~TrapM & ~IntPendingM)); // | FDivBusyE;
assign StallMCause = (wfiM & (~TrapM & ~IntPendingM)) | FDivBusyE;
assign StallWCause = LSUStallM | IFUStallF;

View File

@ -123,25 +123,18 @@ module datapath (
flopenrc #(`XLEN) IFResultWReg(clk, reset, FlushW, ~StallW, IFResultM, IFResultW);
flopenrc #(5) RdWReg(clk, reset, FlushW, ~StallW, RdM, RdW);
// *** simplify WriteDataE in this merge
// floating point interactions: fcvt, fp stores
if (`F_SUPPORTED&(`LLEN>`XLEN)) begin:fpmux
if (`F_SUPPORTED) begin:fpmux
logic [`XLEN-1:0] IFCvtResultW;
mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, IFResultM);
assign WriteDataE = ForwardedSrcBE;
mux2 #(`XLEN) cvtresultmuxW(IFResultW, FCvtIntResW, ~FResSelW[1]&FResSelW[0], IFCvtResultW);
mux5 #(`XLEN) resultmuxW(IFCvtResultW, ReadDataW, CSRReadValW, MDUResultW, SCResultW, ResultSrcW, ResultW);
end else if (`F_SUPPORTED) begin:fpmux
logic [`XLEN-1:0] IFCvtResultW;
mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, IFResultM);
mux2 #(`XLEN) writedatamux(ForwardedSrcBE, FWriteDataE, ~IllegalFPUInstrE, WriteDataE);
mux2 #(`XLEN) cvtresultmuxW(IFResultW, FCvtIntResW, ~FResSelW[1]&FResSelW[0], IFCvtResultW);
mux5 #(`XLEN) resultmuxW(IFCvtResultW, ReadDataW, CSRReadValW, MDUResultW, SCResultW, ResultSrcW, ResultW);
end else begin:fpmux
assign IFResultM = IEUResultM; assign WriteDataE = ForwardedSrcBE;
assign IFResultM = IEUResultM;
mux5 #(`XLEN) resultmuxW(IFResultW, ReadDataW, CSRReadValW, MDUResultW, SCResultW, ResultSrcW, ResultW);
end
assign WriteDataE = ForwardedSrcBE;
// handle Store Conditional result if atomic extension supported
if (`A_SUPPORTED) assign SCResultW = {{(`XLEN-1){1'b0}}, SquashSCW};
else assign SCResultW = 0;