mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Simplified FPU-LSU interface to skip IEU
This commit is contained in:
parent
2e20b3ed72
commit
d556adde16
@ -42,10 +42,9 @@ module fpu (
|
|||||||
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)
|
||||||
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 FStore2, // store two words into memory (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 [`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 [`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] 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)
|
||||||
@ -290,22 +289,18 @@ module fpu (
|
|||||||
// - FP uses NaN-blocking format
|
// - FP uses NaN-blocking format
|
||||||
// - if there are any unsused bits the most significant bits are filled with 1s
|
// - if there are any unsused bits the most significant bits are filled with 1s
|
||||||
|
|
||||||
if(`LLEN==`XLEN)
|
logic [`FLEN-1:0] WriteDataE;
|
||||||
assign FWriteDataE = {{`XLEN-`FLEN{1'b1}}, YE};
|
if(`FPSIZES == 1) assign WriteDataE = YE;
|
||||||
else begin
|
else if(`FPSIZES == 2) assign WriteDataE = FmtE ? YE : {`FLEN/`LEN1{YE[`LEN1-1:0]}};
|
||||||
logic [`FLEN-1:0] WriteDataE;
|
else
|
||||||
if(`FPSIZES == 1) assign WriteDataE = YE;
|
always_comb
|
||||||
else if(`FPSIZES == 2) assign WriteDataE = FmtE ? YE : {`FLEN/`LEN1{YE[`LEN1-1:0]}};
|
case(FmtE)
|
||||||
else
|
`Q_FMT: WriteDataE = YE;
|
||||||
always_comb
|
`D_FMT: WriteDataE = {`FLEN/`D_LEN{YE[`D_LEN-1:0]}};
|
||||||
case(FmtE)
|
`S_FMT: WriteDataE = {`FLEN/`S_LEN{YE[`S_LEN-1:0]}};
|
||||||
`Q_FMT: WriteDataE = YE;
|
`H_FMT: WriteDataE = {`FLEN/`H_LEN{YE[`H_LEN-1:0]}};
|
||||||
`D_FMT: WriteDataE = {`FLEN/`D_LEN{YE[`D_LEN-1:0]}};
|
endcase
|
||||||
`S_FMT: WriteDataE = {`FLEN/`S_LEN{YE[`S_LEN-1:0]}};
|
flopenrc #(`FLEN) EMWriteDataReg (clk, reset, FlushM, ~StallM, WriteDataE, FWriteDataM);
|
||||||
`H_FMT: WriteDataE = {`FLEN/`H_LEN{YE[`H_LEN-1:0]}};
|
|
||||||
endcase
|
|
||||||
flopenrc #(`FLEN) EMWriteDataReg (clk, reset, FlushM, ~StallM, WriteDataE, FWriteDataM);
|
|
||||||
end
|
|
||||||
|
|
||||||
// NaN Block SrcA
|
// NaN Block SrcA
|
||||||
generate
|
generate
|
||||||
|
@ -64,8 +64,10 @@ module hazard(
|
|||||||
assign StallFCause = CSRWriteFencePendingDEM & ~(TrapM | RetM | BPPredWrongE);
|
assign StallFCause = CSRWriteFencePendingDEM & ~(TrapM | RetM | BPPredWrongE);
|
||||||
// stall in decode if instruction is a load/mul/csr dependent on previous
|
// 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 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?)
|
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
|
// 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 StallMCause = (wfiM & (~TrapM & ~IntPendingM)) | FDivBusyE;
|
||||||
assign StallWCause = LSUStallM | IFUStallF;
|
assign StallWCause = LSUStallM | IFUStallF;
|
||||||
|
|
||||||
|
@ -123,25 +123,18 @@ 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);
|
||||||
|
|
||||||
// *** simplify WriteDataE in this merge
|
|
||||||
// floating point interactions: fcvt, fp stores
|
// floating point interactions: fcvt, fp stores
|
||||||
if (`F_SUPPORTED&(`LLEN>`XLEN)) begin:fpmux
|
if (`F_SUPPORTED) begin:fpmux
|
||||||
logic [`XLEN-1:0] IFCvtResultW;
|
logic [`XLEN-1:0] IFCvtResultW;
|
||||||
mux2 #(`XLEN) resultmuxM(IEUResultM, FIntResM, FWriteIntM, IFResultM);
|
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);
|
mux2 #(`XLEN) cvtresultmuxW(IFResultW, FCvtIntResW, ~FResSelW[1]&FResSelW[0], IFCvtResultW);
|
||||||
mux5 #(`XLEN) resultmuxW(IFCvtResultW, ReadDataW, CSRReadValW, MDUResultW, SCResultW, ResultSrcW, ResultW);
|
mux5 #(`XLEN) resultmuxW(IFCvtResultW, ReadDataW, CSRReadValW, MDUResultW, SCResultW, ResultSrcW, ResultW);
|
||||||
end else begin:fpmux
|
end else begin:fpmux
|
||||||
assign IFResultM = IEUResultM; assign WriteDataE = ForwardedSrcBE;
|
assign IFResultM = IEUResultM;
|
||||||
mux5 #(`XLEN) resultmuxW(IFResultW, ReadDataW, CSRReadValW, MDUResultW, SCResultW, ResultSrcW, ResultW);
|
mux5 #(`XLEN) resultmuxW(IFResultW, ReadDataW, CSRReadValW, MDUResultW, SCResultW, ResultSrcW, ResultW);
|
||||||
end
|
end
|
||||||
|
assign WriteDataE = ForwardedSrcBE;
|
||||||
|
|
||||||
// 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};
|
||||||
else assign SCResultW = 0;
|
else assign SCResultW = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user