mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Capitalized LSU and IFU, changed MulDiv to MDU
This commit is contained in:
parent
27c1d73cb1
commit
2df92af488
@ -40,18 +40,18 @@ module ahblite (
|
|||||||
input logic UnsignedLoadM,
|
input logic UnsignedLoadM,
|
||||||
input logic [1:0] AtomicMaskedM,
|
input logic [1:0] AtomicMaskedM,
|
||||||
// Signals from Instruction Cache
|
// Signals from Instruction Cache
|
||||||
input logic [`PA_BITS-1:0] IfuBusAdr,
|
input logic [`PA_BITS-1:0] IFUBusAdr,
|
||||||
input logic IfuBusRead,
|
input logic IFUBusRead,
|
||||||
output logic [`XLEN-1:0] IfuBusHRDATA,
|
output logic [`XLEN-1:0] IFUBusHRDATA,
|
||||||
output logic IfuBusAck,
|
output logic IFUBusAck,
|
||||||
// Signals from Data Cache
|
// Signals from Data Cache
|
||||||
input logic [`PA_BITS-1:0] LsuBusAdr,
|
input logic [`PA_BITS-1:0] LSUBusAdr,
|
||||||
input logic LsuBusRead,
|
input logic LSUBusRead,
|
||||||
input logic LsuBusWrite,
|
input logic LSUBusWrite,
|
||||||
input logic [`XLEN-1:0] LsuBusHWDATA,
|
input logic [`XLEN-1:0] LSUBusHWDATA,
|
||||||
output logic [`XLEN-1:0] LsuBusHRDATA,
|
output logic [`XLEN-1:0] LSUBusHRDATA,
|
||||||
input logic [2:0] LsuBusSize,
|
input logic [2:0] LSUBusSize,
|
||||||
output logic LsuBusAck,
|
output logic LSUBusAck,
|
||||||
// AHB-Lite external signals
|
// AHB-Lite external signals
|
||||||
(* mark_debug = "true" *) input logic [`AHBW-1:0] HRDATA,
|
(* mark_debug = "true" *) input logic [`AHBW-1:0] HRDATA,
|
||||||
(* mark_debug = "true" *) input logic HREADY, HRESP,
|
(* mark_debug = "true" *) input logic HREADY, HRESP,
|
||||||
@ -98,35 +98,35 @@ module ahblite (
|
|||||||
// interface that might be used in place of the ahblite.
|
// interface that might be used in place of the ahblite.
|
||||||
always_comb
|
always_comb
|
||||||
case (BusState)
|
case (BusState)
|
||||||
IDLE: if (LsuBusRead) NextBusState = MEMREAD; // Memory has priority over instructions
|
IDLE: if (LSUBusRead) NextBusState = MEMREAD; // Memory has priority over instructions
|
||||||
else if (LsuBusWrite)NextBusState = MEMWRITE;
|
else if (LSUBusWrite)NextBusState = MEMWRITE;
|
||||||
else if (IfuBusRead) NextBusState = INSTRREAD;
|
else if (IFUBusRead) NextBusState = INSTRREAD;
|
||||||
else NextBusState = IDLE;
|
else NextBusState = IDLE;
|
||||||
MEMREAD: if (~HREADY) NextBusState = MEMREAD;
|
MEMREAD: if (~HREADY) NextBusState = MEMREAD;
|
||||||
else if (IfuBusRead) NextBusState = INSTRREAD;
|
else if (IFUBusRead) NextBusState = INSTRREAD;
|
||||||
else NextBusState = IDLE;
|
else NextBusState = IDLE;
|
||||||
MEMWRITE: if (~HREADY) NextBusState = MEMWRITE;
|
MEMWRITE: if (~HREADY) NextBusState = MEMWRITE;
|
||||||
else if (IfuBusRead) NextBusState = INSTRREAD;
|
else if (IFUBusRead) NextBusState = INSTRREAD;
|
||||||
else NextBusState = IDLE;
|
else NextBusState = IDLE;
|
||||||
INSTRREAD: if (~HREADY) NextBusState = INSTRREAD;
|
INSTRREAD: if (~HREADY) NextBusState = INSTRREAD;
|
||||||
else NextBusState = IDLE; // if (IfuBusRead still high)
|
else NextBusState = IDLE; // if (IFUBusRead still high)
|
||||||
default: NextBusState = IDLE;
|
default: NextBusState = IDLE;
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
|
|
||||||
// bus outputs
|
// bus outputs
|
||||||
assign #1 GrantData = (NextBusState == MEMREAD) | (NextBusState == MEMWRITE);
|
assign #1 GrantData = (NextBusState == MEMREAD) | (NextBusState == MEMWRITE);
|
||||||
assign #1 AccessAddress = (GrantData) ? LsuBusAdr[31:0] : IfuBusAdr[31:0];
|
assign #1 AccessAddress = (GrantData) ? LSUBusAdr[31:0] : IFUBusAdr[31:0];
|
||||||
assign #1 HADDR = AccessAddress;
|
assign #1 HADDR = AccessAddress;
|
||||||
assign ISize = 3'b010; // 32 bit instructions for now; later improve for filling cache with full width; ignored on reads anyway
|
assign ISize = 3'b010; // 32 bit instructions for now; later improve for filling cache with full width; ignored on reads anyway
|
||||||
assign HSIZE = (GrantData) ? {1'b0, LsuBusSize[1:0]} : ISize;
|
assign HSIZE = (GrantData) ? {1'b0, LSUBusSize[1:0]} : ISize;
|
||||||
assign HBURST = 3'b000; // Single burst only supported; consider generalizing for cache fillsfH
|
assign HBURST = 3'b000; // Single burst only supported; consider generalizing for cache fillsfH
|
||||||
assign HPROT = 4'b0011; // not used; see Section 3.7
|
assign HPROT = 4'b0011; // not used; see Section 3.7
|
||||||
assign HTRANS = (NextBusState != IDLE) ? 2'b10 : 2'b00; // NONSEQ if reading or writing, IDLE otherwise
|
assign HTRANS = (NextBusState != IDLE) ? 2'b10 : 2'b00; // NONSEQ if reading or writing, IDLE otherwise
|
||||||
assign HMASTLOCK = 0; // no locking supported
|
assign HMASTLOCK = 0; // no locking supported
|
||||||
assign HWRITE = NextBusState == MEMWRITE;
|
assign HWRITE = NextBusState == MEMWRITE;
|
||||||
// delay write data by one cycle for
|
// delay write data by one cycle for
|
||||||
flop #(`XLEN) wdreg(HCLK, LsuBusHWDATA, HWDATA); // delay HWDATA by 1 cycle per spec; *** assumes AHBW = XLEN
|
flop #(`XLEN) wdreg(HCLK, LSUBusHWDATA, HWDATA); // delay HWDATA by 1 cycle per spec; *** assumes AHBW = XLEN
|
||||||
// delay signals for subword writes
|
// delay signals for subword writes
|
||||||
flop #(3) adrreg(HCLK, HADDR[2:0], HADDRD);
|
flop #(3) adrreg(HCLK, HADDR[2:0], HADDRD);
|
||||||
flop #(4) sizereg(HCLK, {UnsignedLoadM, HSIZE}, HSIZED);
|
flop #(4) sizereg(HCLK, {UnsignedLoadM, HSIZE}, HSIZED);
|
||||||
@ -136,9 +136,9 @@ module ahblite (
|
|||||||
// *** assumes AHBW = XLEN
|
// *** assumes AHBW = XLEN
|
||||||
|
|
||||||
|
|
||||||
assign IfuBusHRDATA = HRDATA;
|
assign IFUBusHRDATA = HRDATA;
|
||||||
assign LsuBusHRDATA = HRDATA;
|
assign LSUBusHRDATA = HRDATA;
|
||||||
assign IfuBusAck = (BusState == INSTRREAD) & (NextBusState != INSTRREAD);
|
assign IFUBusAck = (BusState == INSTRREAD) & (NextBusState != INSTRREAD);
|
||||||
assign LsuBusAck = (BusState == MEMREAD) & (NextBusState != MEMREAD) | (BusState == MEMWRITE) & (NextBusState != MEMWRITE);
|
assign LSUBusAck = (BusState == MEMREAD) & (NextBusState != MEMREAD) | (BusState == MEMWRITE) & (NextBusState != MEMWRITE);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -28,8 +28,8 @@
|
|||||||
module hazard(
|
module hazard(
|
||||||
// Detect hazards
|
// Detect hazards
|
||||||
(* mark_debug = "true" *) input logic BPPredWrongE, CSRWritePendingDEM, RetM, TrapM,
|
(* mark_debug = "true" *) input logic BPPredWrongE, CSRWritePendingDEM, RetM, TrapM,
|
||||||
(* mark_debug = "true" *) input logic LoadStallD, StoreStallD, MulDivStallD, CSRRdStallD,
|
(* mark_debug = "true" *) input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD,
|
||||||
(* mark_debug = "true" *) input logic LSUStall, IfuStallF,
|
(* mark_debug = "true" *) input logic LSUStall, IFUStallF,
|
||||||
(* mark_debug = "true" *) input logic FPUStallD, FStallD,
|
(* mark_debug = "true" *) input logic FPUStallD, FStallD,
|
||||||
(* mark_debug = "true" *) input logic DivBusyE,FDivBusyE,
|
(* mark_debug = "true" *) input logic DivBusyE,FDivBusyE,
|
||||||
(* mark_debug = "true" *) input logic EcallFaultM, BreakpointFaultM,
|
(* mark_debug = "true" *) input logic EcallFaultM, BreakpointFaultM,
|
||||||
@ -56,10 +56,10 @@ module hazard(
|
|||||||
// If any stages are stalled, the first stage that isn't stalled must flush.
|
// If any stages are stalled, the first stage that isn't stalled must flush.
|
||||||
|
|
||||||
assign StallFCause = CSRWritePendingDEM & ~(TrapM | RetM | BPPredWrongE);
|
assign StallFCause = CSRWritePendingDEM & ~(TrapM | RetM | BPPredWrongE);
|
||||||
assign StallDCause = (LoadStallD | StoreStallD | MulDivStallD | CSRRdStallD | FPUStallD | FStallD) & ~(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); // stall in decode if instruction is a load/mul/csr dependent on previous
|
||||||
assign StallECause = DivBusyE | FDivBusyE;
|
assign StallECause = DivBusyE | FDivBusyE;
|
||||||
assign StallMCause = 0;
|
assign StallMCause = 0;
|
||||||
assign StallWCause = LSUStall | IfuStallF;
|
assign StallWCause = LSUStall | IFUStallF;
|
||||||
|
|
||||||
assign StallF = StallFCause | StallD;
|
assign StallF = StallFCause | StallD;
|
||||||
assign StallD = StallDCause | StallE;
|
assign StallD = StallDCause | StallE;
|
||||||
|
@ -44,7 +44,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 MulDivE, W64E,
|
output logic MDUE, W64E,
|
||||||
output logic JumpE,
|
output logic JumpE,
|
||||||
// Memory stage control signals
|
// Memory stage control signals
|
||||||
input logic StallM, FlushM,
|
input logic StallM, FlushM,
|
||||||
@ -83,7 +83,7 @@ module controller(
|
|||||||
logic ALUOpD;
|
logic ALUOpD;
|
||||||
logic [2:0] ALUControlD;
|
logic [2:0] ALUControlD;
|
||||||
logic ALUSrcAD, ALUSrcBD;
|
logic ALUSrcAD, ALUSrcBD;
|
||||||
logic ALUResultSrcD, W64D, MulDivD;
|
logic ALUResultSrcD, W64D, MDUD;
|
||||||
logic CSRZeroSrcD;
|
logic CSRZeroSrcD;
|
||||||
logic CSRReadD;
|
logic CSRReadD;
|
||||||
logic [1:0] AtomicD;
|
logic [1:0] AtomicD;
|
||||||
@ -111,7 +111,7 @@ module controller(
|
|||||||
// Main Instruction Decoder
|
// Main Instruction Decoder
|
||||||
always_comb
|
always_comb
|
||||||
case(OpD)
|
case(OpD)
|
||||||
// RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_ALUResultSrc_W64_CSRRead_Privileged_Fence_MulDiv_Atomic_Illegal
|
// RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_ALUResultSrc_W64_CSRRead_Privileged_Fence_MDU_Atomic_Illegal
|
||||||
7'b0000000: ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // illegal instruction
|
7'b0000000: ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // illegal instruction
|
||||||
7'b0000011: ControlsD = `CTRLW'b1_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // lw
|
7'b0000011: ControlsD = `CTRLW'b1_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // lw
|
||||||
7'b0000111: ControlsD = `CTRLW'b0_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // flw
|
7'b0000111: ControlsD = `CTRLW'b0_000_01_10_001_0_0_0_0_0_0_0_0_0_00_0; // flw
|
||||||
@ -162,7 +162,7 @@ module controller(
|
|||||||
assign IllegalBaseInstrFaultD = ControlsD[0];
|
assign IllegalBaseInstrFaultD = ControlsD[0];
|
||||||
assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD,
|
assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD,
|
||||||
ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, W64D, CSRReadD,
|
ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, W64D, CSRReadD,
|
||||||
PrivilegedD, FenceD, MulDivD, AtomicD, unused} = IllegalIEUInstrFaultD ? `CTRLW'b0 : ControlsD;
|
PrivilegedD, FenceD, MDUD, AtomicD, unused} = IllegalIEUInstrFaultD ? `CTRLW'b0 : ControlsD;
|
||||||
// *** move Privileged, CSRwrite?? Or move controller out of IEU into datapath and handle all instructions
|
// *** move Privileged, CSRwrite?? Or move controller out of IEU into datapath and handle all instructions
|
||||||
|
|
||||||
assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source?
|
assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source?
|
||||||
@ -194,8 +194,8 @@ module controller(
|
|||||||
|
|
||||||
// Execute stage pipeline control register and logic
|
// Execute stage pipeline control register and logic
|
||||||
flopenrc #(27) controlregE(clk, reset, FlushE, ~StallE,
|
flopenrc #(27) controlregE(clk, reset, FlushE, ~StallE,
|
||||||
{RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MulDivD, AtomicD, InvalidateICacheD, FlushDCacheD, InstrValidD},
|
{RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, InstrValidD},
|
||||||
{IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE});
|
{IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE});
|
||||||
|
|
||||||
// Branch Logic
|
// Branch Logic
|
||||||
assign {eqE, ltE, ltuE} = FlagsE;
|
assign {eqE, ltE, ltuE} = FlagsE;
|
||||||
|
@ -58,7 +58,7 @@ module datapath (
|
|||||||
input logic [2:0] ResultSrcW,
|
input logic [2:0] ResultSrcW,
|
||||||
output logic [`XLEN-1:0] ReadDataW,
|
output logic [`XLEN-1:0] ReadDataW,
|
||||||
// input logic [`XLEN-1:0] PCLinkW,
|
// input logic [`XLEN-1:0] PCLinkW,
|
||||||
input logic [`XLEN-1:0] CSRReadValW, ReadDataM, MulDivResultW,
|
input logic [`XLEN-1:0] CSRReadValW, ReadDataM, MDUResultW,
|
||||||
// Hazard Unit signals
|
// Hazard Unit signals
|
||||||
output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E,
|
output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E,
|
||||||
output logic [4:0] RdE, RdM, RdW
|
output logic [4:0] RdE, RdM, RdW
|
||||||
@ -121,7 +121,7 @@ module datapath (
|
|||||||
flopenrc #(`XLEN) ResultWReg(clk, reset, FlushW, ~StallW, ResultM, ResultW);
|
flopenrc #(`XLEN) ResultWReg(clk, reset, FlushW, ~StallW, ResultM, ResultW);
|
||||||
flopenrc #(5) RdWReg(clk, reset, FlushW, ~StallW, RdM, RdW);
|
flopenrc #(5) RdWReg(clk, reset, FlushW, ~StallW, RdM, RdW);
|
||||||
flopen #(`XLEN) ReadDataWReg(.clk, .en(~StallW), .d(ReadDataM), .q(ReadDataW));
|
flopen #(`XLEN) ReadDataWReg(.clk, .en(~StallW), .d(ReadDataM), .q(ReadDataW));
|
||||||
mux5 #(`XLEN) resultmuxW(ResultW, ReadDataW, CSRReadValW, MulDivResultW, SCResultW, ResultSrcW, WriteDataW);
|
mux5 #(`XLEN) resultmuxW(ResultW, ReadDataW, CSRReadValW, MDUResultW, SCResultW, ResultSrcW, WriteDataW);
|
||||||
|
|
||||||
// floating point interactions: fcvt, fp stores
|
// floating point interactions: fcvt, fp stores
|
||||||
if (`F_SUPPORTED) begin:fpmux
|
if (`F_SUPPORTED) begin:fpmux
|
||||||
|
@ -28,13 +28,13 @@
|
|||||||
module forward(
|
module forward(
|
||||||
// Detect hazards
|
// Detect hazards
|
||||||
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, MulDivE, CSRReadE,
|
input logic MemReadE, MDUE, CSRReadE,
|
||||||
input logic RegWriteM, RegWriteW,
|
input logic RegWriteM, RegWriteW,
|
||||||
input logic FWriteIntE,
|
input logic FWriteIntE,
|
||||||
input logic SCE,
|
input logic SCE,
|
||||||
// Forwarding controls
|
// Forwarding controls
|
||||||
output logic [1:0] ForwardAE, ForwardBE,
|
output logic [1:0] ForwardAE, ForwardBE,
|
||||||
output logic FPUStallD, LoadStallD, MulDivStallD, CSRRdStallD
|
output logic FPUStallD, LoadStallD, MDUStallD, CSRRdStallD
|
||||||
);
|
);
|
||||||
|
|
||||||
logic MatchDE;
|
logic MatchDE;
|
||||||
@ -55,6 +55,6 @@ module forward(
|
|||||||
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 = FWriteIntE & MatchDE;
|
assign FPUStallD = FWriteIntE & MatchDE;
|
||||||
assign LoadStallD = (MemReadE|SCE) & MatchDE;
|
assign LoadStallD = (MemReadE|SCE) & MatchDE;
|
||||||
assign MulDivStallD = MulDivE & MatchDE;
|
assign MDUStallD = MDUE & MatchDE;
|
||||||
assign CSRRdStallD = CSRReadE & MatchDE;
|
assign CSRRdStallD = CSRReadE & MatchDE;
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -38,7 +38,7 @@ module ieu (
|
|||||||
input logic IllegalFPUInstrE,
|
input logic IllegalFPUInstrE,
|
||||||
input logic [`XLEN-1:0] FWriteDataE,
|
input logic [`XLEN-1:0] FWriteDataE,
|
||||||
output logic [`XLEN-1:0] IEUAdrE,
|
output logic [`XLEN-1:0] IEUAdrE,
|
||||||
output logic MulDivE, W64E,
|
output logic MDUE, 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
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ module ieu (
|
|||||||
output logic InvalidateICacheM, FlushDCacheM,
|
output logic InvalidateICacheM, FlushDCacheM,
|
||||||
|
|
||||||
// Writeback stage
|
// Writeback stage
|
||||||
input logic [`XLEN-1:0] CSRReadValW, ReadDataM, MulDivResultW,
|
input logic [`XLEN-1:0] CSRReadValW, ReadDataM, MDUResultW,
|
||||||
output logic [4:0] RdW,
|
output logic [4:0] RdW,
|
||||||
output logic [`XLEN-1:0] ReadDataW,
|
output logic [`XLEN-1:0] ReadDataW,
|
||||||
// input logic [`XLEN-1:0] PCLinkW,
|
// input logic [`XLEN-1:0] PCLinkW,
|
||||||
@ -64,7 +64,7 @@ module ieu (
|
|||||||
// hazards
|
// hazards
|
||||||
input logic StallD, StallE, StallM, StallW,
|
input logic StallD, StallE, StallM, StallW,
|
||||||
input logic FlushD, FlushE, FlushM, FlushW,
|
input logic FlushD, FlushE, FlushM, FlushW,
|
||||||
output logic FPUStallD, LoadStallD, MulDivStallD, CSRRdStallD,
|
output logic FPUStallD, LoadStallD, MDUStallD, CSRRdStallD,
|
||||||
output logic PCSrcE,
|
output logic PCSrcE,
|
||||||
output logic CSRReadM, CSRWriteM, PrivilegedM,
|
output logic CSRReadM, CSRWriteM, PrivilegedM,
|
||||||
output logic CSRWritePendingDEM,
|
output logic CSRWritePendingDEM,
|
||||||
@ -92,7 +92,7 @@ module ieu (
|
|||||||
.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, .MulDivE, .W64E, .JumpE, .StallM, .FlushM, .MemRWM,
|
.Funct3E, .MDUE, .W64E, .JumpE, .StallM, .FlushM, .MemRWM,
|
||||||
.CSRReadM, .CSRWriteM, .PrivilegedM, .SCE, .AtomicE, .AtomicM, .Funct3M,
|
.CSRReadM, .CSRWriteM, .PrivilegedM, .SCE, .AtomicE, .AtomicM, .Funct3M,
|
||||||
.RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .FWriteIntM,
|
.RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .FWriteIntM,
|
||||||
.StallW, .FlushW, .RegWriteW, .ResultSrcW, .CSRWritePendingDEM, .StoreStallD);
|
.StallW, .FlushW, .RegWriteW, .ResultSrcW, .CSRWritePendingDEM, .StoreStallD);
|
||||||
@ -103,12 +103,12 @@ module ieu (
|
|||||||
.FWriteDataE, .PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE,
|
.FWriteDataE, .PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE,
|
||||||
.StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM,
|
.StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM,
|
||||||
.StallW, .FlushW, .RegWriteW, .SquashSCW, .ResultSrcW, .ReadDataW,
|
.StallW, .FlushW, .RegWriteW, .SquashSCW, .ResultSrcW, .ReadDataW,
|
||||||
.CSRReadValW, .ReadDataM, .MulDivResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW);
|
.CSRReadValW, .ReadDataM, .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, .MulDivE, .CSRReadE, .RegWriteM, .RegWriteW,
|
.MemReadE, .MDUE, .CSRReadE, .RegWriteM, .RegWriteW,
|
||||||
.FWriteIntE, .SCE, .ForwardAE, .ForwardBE,
|
.FWriteIntE, .SCE, .ForwardAE, .ForwardBE,
|
||||||
.FPUStallD, .LoadStallD, .MulDivStallD, .CSRRdStallD);
|
.FPUStallD, .LoadStallD, .MDUStallD, .CSRRdStallD);
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -31,11 +31,11 @@ module ifu (
|
|||||||
input logic StallF, StallD, StallE, StallM, StallW,
|
input logic StallF, StallD, StallE, StallM, StallW,
|
||||||
input logic FlushF, FlushD, FlushE, FlushM, FlushW,
|
input logic FlushF, FlushD, FlushE, FlushM, FlushW,
|
||||||
// Bus interface
|
// Bus interface
|
||||||
(* mark_debug = "true" *) input logic [`XLEN-1:0] IfuBusHRDATA,
|
(* mark_debug = "true" *) input logic [`XLEN-1:0] IFUBusHRDATA,
|
||||||
(* mark_debug = "true" *) input logic IfuBusAck,
|
(* mark_debug = "true" *) input logic IFUBusAck,
|
||||||
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] IfuBusAdr,
|
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] IFUBusAdr,
|
||||||
(* mark_debug = "true" *) output logic IfuBusRead,
|
(* mark_debug = "true" *) output logic IFUBusRead,
|
||||||
(* mark_debug = "true" *) output logic IfuStallF,
|
(* mark_debug = "true" *) output logic IFUStallF,
|
||||||
(* mark_debug = "true" *) output logic [`XLEN-1:0] PCF,
|
(* mark_debug = "true" *) output logic [`XLEN-1:0] PCF,
|
||||||
// Execute
|
// Execute
|
||||||
output logic [`XLEN-1:0] PCLinkE,
|
output logic [`XLEN-1:0] PCLinkE,
|
||||||
@ -210,8 +210,8 @@ module ifu (
|
|||||||
|
|
||||||
// *** put memory interface on here, InstrF becomes output
|
// *** put memory interface on here, InstrF becomes output
|
||||||
//assign ICacheBusAdr = PCF; // *** no MMU
|
//assign ICacheBusAdr = PCF; // *** no MMU
|
||||||
//assign IfuBusFetch = ~StallD; // *** & ICacheMissF; add later
|
//assign IFUBusFetch = ~StallD; // *** & ICacheMissF; add later
|
||||||
// assign IfuBusFetch = 1; // *** & ICacheMissF; add later
|
// assign IFUBusFetch = 1; // *** & ICacheMissF; add later
|
||||||
|
|
||||||
// conditional
|
// conditional
|
||||||
// 1. ram // controlled by `MEM_IROM
|
// 1. ram // controlled by `MEM_IROM
|
||||||
@ -229,13 +229,13 @@ module ifu (
|
|||||||
logic [LOGWPL-1:0] WordCount;
|
logic [LOGWPL-1:0] WordCount;
|
||||||
logic [LINELEN-1:0] ICacheMemWriteData;
|
logic [LINELEN-1:0] ICacheMemWriteData;
|
||||||
logic ICacheBusAck;
|
logic ICacheBusAck;
|
||||||
logic [`PA_BITS-1:0] LocalIfuBusAdr;
|
logic [`PA_BITS-1:0] LocalIFUBusAdr;
|
||||||
logic [`PA_BITS-1:0] ICacheBusAdr;
|
logic [`PA_BITS-1:0] ICacheBusAdr;
|
||||||
logic SelUncachedAdr;
|
logic SelUncachedAdr;
|
||||||
|
|
||||||
if(`MEM_ICACHE) begin : icache
|
if(`MEM_ICACHE) begin : icache
|
||||||
logic [1:0] IfuRWF;
|
logic [1:0] IFURWF;
|
||||||
assign IfuRWF = CacheableF ? 2'b10 : 2'b00;
|
assign IFURWF = CacheableF ? 2'b10 : 2'b00;
|
||||||
|
|
||||||
/* -----\/----- EXCLUDED -----\/-----
|
/* -----\/----- EXCLUDED -----\/-----
|
||||||
icache #(.LINELEN(`ICACHE_LINELENINBITS),
|
icache #(.LINELEN(`ICACHE_LINELENINBITS),
|
||||||
@ -244,7 +244,7 @@ module ifu (
|
|||||||
icache(.clk, .reset, .CPUBusy, .IgnoreRequest, .ICacheMemWriteData , .ICacheBusAck,
|
icache(.clk, .reset, .CPUBusy, .IgnoreRequest, .ICacheMemWriteData , .ICacheBusAck,
|
||||||
.ICacheBusAdr, .ICacheStallF, .FinalInstrRawF,
|
.ICacheBusAdr, .ICacheStallF, .FinalInstrRawF,
|
||||||
.ICacheFetchLine,
|
.ICacheFetchLine,
|
||||||
.IfuRWF(IfuRWF), //aways read
|
.IFURWF(IFURWF), //aways read
|
||||||
.PCNextF(PCNextFMux),
|
.PCNextF(PCNextFMux),
|
||||||
.PCPF(PCPF),
|
.PCPF(PCPF),
|
||||||
.PCF(PCFMux),
|
.PCF(PCFMux),
|
||||||
@ -264,7 +264,7 @@ module ifu (
|
|||||||
.CacheMiss(),
|
.CacheMiss(),
|
||||||
.CacheAccess(),
|
.CacheAccess(),
|
||||||
.FinalWriteData('0),
|
.FinalWriteData('0),
|
||||||
.RW(IfuRWF),
|
.RW(IFURWF),
|
||||||
.Atomic(2'b00),
|
.Atomic(2'b00),
|
||||||
.FlushCache(1'b0),
|
.FlushCache(1'b0),
|
||||||
.NextAdr(PCNextFMux),
|
.NextAdr(PCNextFMux),
|
||||||
@ -293,23 +293,23 @@ module ifu (
|
|||||||
genvar index;
|
genvar index;
|
||||||
for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer
|
for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer
|
||||||
flopen #(`XLEN) fb(.clk(clk),
|
flopen #(`XLEN) fb(.clk(clk),
|
||||||
.en(IfuBusAck & IfuBusRead & (index == WordCount)),
|
.en(IFUBusAck & IFUBusRead & (index == WordCount)),
|
||||||
.d(IfuBusHRDATA),
|
.d(IFUBusHRDATA),
|
||||||
.q(ICacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN]));
|
.q(ICacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN]));
|
||||||
end
|
end
|
||||||
|
|
||||||
assign LocalIfuBusAdr = SelUncachedAdr ? PCPF : ICacheBusAdr;
|
assign LocalIFUBusAdr = SelUncachedAdr ? PCPF : ICacheBusAdr;
|
||||||
assign IfuBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalIfuBusAdr;
|
assign IFUBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalIFUBusAdr;
|
||||||
|
|
||||||
busfsm #(WordCountThreshold, LOGWPL, `MEM_ICACHE)
|
busfsm #(WordCountThreshold, LOGWPL, `MEM_ICACHE)
|
||||||
busfsm(.clk, .reset, .IgnoreRequest,
|
busfsm(.clk, .reset, .IgnoreRequest,
|
||||||
.LsuRWM(2'b10), .DCacheFetchLine(ICacheFetchLine), .DCacheWriteLine(1'b0),
|
.LSURWM(2'b10), .DCacheFetchLine(ICacheFetchLine), .DCacheWriteLine(1'b0),
|
||||||
.LsuBusAck(IfuBusAck),
|
.LSUBusAck(IFUBusAck),
|
||||||
.CPUBusy, .CacheableM(CacheableF),
|
.CPUBusy, .CacheableM(CacheableF),
|
||||||
.BusStall, .LsuBusWrite(), .LsuBusRead(IfuBusRead), .DCacheBusAck(ICacheBusAck),
|
.BusStall, .LSUBusWrite(), .LSUBusRead(IFUBusRead), .DCacheBusAck(ICacheBusAck),
|
||||||
.BusCommittedM(), .SelUncachedAdr(SelUncachedAdr), .WordCount);
|
.BusCommittedM(), .SelUncachedAdr(SelUncachedAdr), .WordCount);
|
||||||
|
|
||||||
assign IfuStallF = ICacheStallF | BusStall | SelNextSpill;
|
assign IFUStallF = ICacheStallF | BusStall | SelNextSpill;
|
||||||
assign CPUBusy = StallF & ~SelNextSpill;
|
assign CPUBusy = StallF & ~SelNextSpill;
|
||||||
|
|
||||||
//assign IgnoreRequest = ITLBMissF | ExceptionM | PendingInterruptM;
|
//assign IgnoreRequest = ITLBMissF | ExceptionM | PendingInterruptM;
|
||||||
|
@ -32,16 +32,16 @@ module busfsm #(parameter integer WordCountThreshold,
|
|||||||
input logic reset,
|
input logic reset,
|
||||||
|
|
||||||
input logic IgnoreRequest,
|
input logic IgnoreRequest,
|
||||||
input logic [1:0] LsuRWM,
|
input logic [1:0] LSURWM,
|
||||||
input logic DCacheFetchLine,
|
input logic DCacheFetchLine,
|
||||||
input logic DCacheWriteLine,
|
input logic DCacheWriteLine,
|
||||||
input logic LsuBusAck,
|
input logic LSUBusAck,
|
||||||
input logic CPUBusy,
|
input logic CPUBusy,
|
||||||
input logic CacheableM,
|
input logic CacheableM,
|
||||||
|
|
||||||
output logic BusStall,
|
output logic BusStall,
|
||||||
output logic LsuBusWrite,
|
output logic LSUBusWrite,
|
||||||
output logic LsuBusRead,
|
output logic LSUBusRead,
|
||||||
output logic DCacheBusAck,
|
output logic DCacheBusAck,
|
||||||
output logic BusCommittedM,
|
output logic BusCommittedM,
|
||||||
output logic SelUncachedAdr,
|
output logic SelUncachedAdr,
|
||||||
@ -49,8 +49,8 @@ module busfsm #(parameter integer WordCountThreshold,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
logic UnCachedLsuBusRead;
|
logic UnCachedLSUBusRead;
|
||||||
logic UnCachedLsuBusWrite;
|
logic UnCachedLSUBusWrite;
|
||||||
logic CntEn, PreCntEn;
|
logic CntEn, PreCntEn;
|
||||||
logic CntReset;
|
logic CntReset;
|
||||||
logic WordCountFlag;
|
logic WordCountFlag;
|
||||||
@ -80,7 +80,7 @@ module busfsm #(parameter integer WordCountThreshold,
|
|||||||
assign NextWordCount = WordCount + 1'b1;
|
assign NextWordCount = WordCount + 1'b1;
|
||||||
|
|
||||||
assign WordCountFlag = (WordCount == WordCountThreshold[LOGWPL-1:0]);
|
assign WordCountFlag = (WordCount == WordCountThreshold[LOGWPL-1:0]);
|
||||||
assign CntEn = PreCntEn & LsuBusAck;
|
assign CntEn = PreCntEn & LSUBusAck;
|
||||||
|
|
||||||
assign UnCachedAccess = ~CacheEnabled | ~CacheableM;
|
assign UnCachedAccess = ~CacheEnabled | ~CacheableM;
|
||||||
|
|
||||||
@ -91,14 +91,14 @@ module busfsm #(parameter integer WordCountThreshold,
|
|||||||
always_comb begin
|
always_comb begin
|
||||||
case(BusCurrState)
|
case(BusCurrState)
|
||||||
STATE_BUS_READY: if(IgnoreRequest) BusNextState = STATE_BUS_READY;
|
STATE_BUS_READY: if(IgnoreRequest) BusNextState = STATE_BUS_READY;
|
||||||
else if(LsuRWM[0] & (UnCachedAccess)) BusNextState = STATE_BUS_UNCACHED_WRITE;
|
else if(LSURWM[0] & (UnCachedAccess)) BusNextState = STATE_BUS_UNCACHED_WRITE;
|
||||||
else if(LsuRWM[1] & (UnCachedAccess)) BusNextState = STATE_BUS_UNCACHED_READ;
|
else if(LSURWM[1] & (UnCachedAccess)) BusNextState = STATE_BUS_UNCACHED_READ;
|
||||||
else if(DCacheFetchLine) BusNextState = STATE_BUS_FETCH;
|
else if(DCacheFetchLine) BusNextState = STATE_BUS_FETCH;
|
||||||
else if(DCacheWriteLine) BusNextState = STATE_BUS_WRITE;
|
else if(DCacheWriteLine) BusNextState = STATE_BUS_WRITE;
|
||||||
else BusNextState = STATE_BUS_READY;
|
else BusNextState = STATE_BUS_READY;
|
||||||
STATE_BUS_UNCACHED_WRITE: if(LsuBusAck) BusNextState = STATE_BUS_UNCACHED_WRITE_DONE;
|
STATE_BUS_UNCACHED_WRITE: if(LSUBusAck) BusNextState = STATE_BUS_UNCACHED_WRITE_DONE;
|
||||||
else BusNextState = STATE_BUS_UNCACHED_WRITE;
|
else BusNextState = STATE_BUS_UNCACHED_WRITE;
|
||||||
STATE_BUS_UNCACHED_READ: if(LsuBusAck) BusNextState = STATE_BUS_UNCACHED_READ_DONE;
|
STATE_BUS_UNCACHED_READ: if(LSUBusAck) BusNextState = STATE_BUS_UNCACHED_READ_DONE;
|
||||||
else BusNextState = STATE_BUS_UNCACHED_READ;
|
else BusNextState = STATE_BUS_UNCACHED_READ;
|
||||||
STATE_BUS_UNCACHED_WRITE_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY;
|
STATE_BUS_UNCACHED_WRITE_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY;
|
||||||
else BusNextState = STATE_BUS_READY;
|
else BusNextState = STATE_BUS_READY;
|
||||||
@ -106,9 +106,9 @@ module busfsm #(parameter integer WordCountThreshold,
|
|||||||
else BusNextState = STATE_BUS_READY;
|
else BusNextState = STATE_BUS_READY;
|
||||||
STATE_BUS_CPU_BUSY: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY;
|
STATE_BUS_CPU_BUSY: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY;
|
||||||
else BusNextState = STATE_BUS_READY;
|
else BusNextState = STATE_BUS_READY;
|
||||||
STATE_BUS_FETCH: if (WordCountFlag & LsuBusAck) BusNextState = STATE_BUS_READY;
|
STATE_BUS_FETCH: if (WordCountFlag & LSUBusAck) BusNextState = STATE_BUS_READY;
|
||||||
else BusNextState = STATE_BUS_FETCH;
|
else BusNextState = STATE_BUS_FETCH;
|
||||||
STATE_BUS_WRITE: if(WordCountFlag & LsuBusAck) BusNextState = STATE_BUS_READY;
|
STATE_BUS_WRITE: if(WordCountFlag & LSUBusAck) BusNextState = STATE_BUS_READY;
|
||||||
else BusNextState = STATE_BUS_WRITE;
|
else BusNextState = STATE_BUS_WRITE;
|
||||||
default: BusNextState = STATE_BUS_READY;
|
default: BusNextState = STATE_BUS_READY;
|
||||||
endcase
|
endcase
|
||||||
@ -116,24 +116,24 @@ module busfsm #(parameter integer WordCountThreshold,
|
|||||||
|
|
||||||
|
|
||||||
assign CntReset = BusCurrState == STATE_BUS_READY;
|
assign CntReset = BusCurrState == STATE_BUS_READY;
|
||||||
assign BusStall = (BusCurrState == STATE_BUS_READY & ~IgnoreRequest & ((UnCachedAccess & (|LsuRWM)) | DCacheFetchLine | DCacheWriteLine)) |
|
assign BusStall = (BusCurrState == STATE_BUS_READY & ~IgnoreRequest & ((UnCachedAccess & (|LSURWM)) | DCacheFetchLine | DCacheWriteLine)) |
|
||||||
(BusCurrState == STATE_BUS_UNCACHED_WRITE) |
|
(BusCurrState == STATE_BUS_UNCACHED_WRITE) |
|
||||||
(BusCurrState == STATE_BUS_UNCACHED_READ) |
|
(BusCurrState == STATE_BUS_UNCACHED_READ) |
|
||||||
(BusCurrState == STATE_BUS_FETCH) |
|
(BusCurrState == STATE_BUS_FETCH) |
|
||||||
(BusCurrState == STATE_BUS_WRITE);
|
(BusCurrState == STATE_BUS_WRITE);
|
||||||
assign PreCntEn = BusCurrState == STATE_BUS_FETCH | BusCurrState == STATE_BUS_WRITE;
|
assign PreCntEn = BusCurrState == STATE_BUS_FETCH | BusCurrState == STATE_BUS_WRITE;
|
||||||
assign UnCachedLsuBusWrite = (BusCurrState == STATE_BUS_READY & UnCachedAccess & (LsuRWM[0])) |
|
assign UnCachedLSUBusWrite = (BusCurrState == STATE_BUS_READY & UnCachedAccess & (LSURWM[0])) |
|
||||||
(BusCurrState == STATE_BUS_UNCACHED_WRITE);
|
(BusCurrState == STATE_BUS_UNCACHED_WRITE);
|
||||||
assign LsuBusWrite = UnCachedLsuBusWrite | (BusCurrState == STATE_BUS_WRITE);
|
assign LSUBusWrite = UnCachedLSUBusWrite | (BusCurrState == STATE_BUS_WRITE);
|
||||||
|
|
||||||
assign UnCachedLsuBusRead = (BusCurrState == STATE_BUS_READY & UnCachedAccess & (|LsuRWM[1])) |
|
assign UnCachedLSUBusRead = (BusCurrState == STATE_BUS_READY & UnCachedAccess & (|LSURWM[1])) |
|
||||||
(BusCurrState == STATE_BUS_UNCACHED_READ);
|
(BusCurrState == STATE_BUS_UNCACHED_READ);
|
||||||
assign LsuBusRead = UnCachedLsuBusRead | (BusCurrState == STATE_BUS_FETCH) | (BusCurrState == STATE_BUS_READY & DCacheFetchLine);
|
assign LSUBusRead = UnCachedLSUBusRead | (BusCurrState == STATE_BUS_FETCH) | (BusCurrState == STATE_BUS_READY & DCacheFetchLine);
|
||||||
|
|
||||||
assign DCacheBusAck = (BusCurrState == STATE_BUS_FETCH & WordCountFlag & LsuBusAck) |
|
assign DCacheBusAck = (BusCurrState == STATE_BUS_FETCH & WordCountFlag & LSUBusAck) |
|
||||||
(BusCurrState == STATE_BUS_WRITE & WordCountFlag & LsuBusAck);
|
(BusCurrState == STATE_BUS_WRITE & WordCountFlag & LSUBusAck);
|
||||||
assign BusCommittedM = BusCurrState != STATE_BUS_READY;
|
assign BusCommittedM = BusCurrState != STATE_BUS_READY;
|
||||||
assign SelUncachedAdr = (BusCurrState == STATE_BUS_READY & (|LsuRWM & UnCachedAccess)) |
|
assign SelUncachedAdr = (BusCurrState == STATE_BUS_READY & (|LSURWM & UnCachedAccess)) |
|
||||||
(BusCurrState == STATE_BUS_UNCACHED_READ |
|
(BusCurrState == STATE_BUS_UNCACHED_READ |
|
||||||
BusCurrState == STATE_BUS_UNCACHED_READ_DONE |
|
BusCurrState == STATE_BUS_UNCACHED_READ_DONE |
|
||||||
BusCurrState == STATE_BUS_UNCACHED_WRITE |
|
BusCurrState == STATE_BUS_UNCACHED_WRITE |
|
||||||
|
@ -31,10 +31,10 @@ module lrsc
|
|||||||
input logic clk, reset,
|
input logic clk, reset,
|
||||||
input logic FlushW, CPUBusy,
|
input logic FlushW, CPUBusy,
|
||||||
input logic MemReadM,
|
input logic MemReadM,
|
||||||
input logic [1:0] PreLsuRWM,
|
input logic [1:0] PreLSURWM,
|
||||||
output logic [1:0] LsuRWM,
|
output logic [1:0] LSURWM,
|
||||||
input logic [1:0] LsuAtomicM,
|
input logic [1:0] LSUAtomicM,
|
||||||
input logic [`PA_BITS-1:0] LsuPAdrM, // from mmu to dcache
|
input logic [`PA_BITS-1:0] LSUPAdrM, // from mmu to dcache
|
||||||
output logic SquashSCW
|
output logic SquashSCW
|
||||||
);
|
);
|
||||||
// Handle atomic load reserved / store conditional
|
// Handle atomic load reserved / store conditional
|
||||||
@ -43,17 +43,17 @@ module lrsc
|
|||||||
logic lrM, scM, WriteAdrMatchM;
|
logic lrM, scM, WriteAdrMatchM;
|
||||||
logic SquashSCM;
|
logic SquashSCM;
|
||||||
|
|
||||||
assign lrM = MemReadM & LsuAtomicM[0];
|
assign lrM = MemReadM & LSUAtomicM[0];
|
||||||
assign scM = PreLsuRWM[0] & LsuAtomicM[0];
|
assign scM = PreLSURWM[0] & LSUAtomicM[0];
|
||||||
assign WriteAdrMatchM = PreLsuRWM[0] & (LsuPAdrM[`PA_BITS-1:2] == ReservationPAdrW) & ReservationValidW;
|
assign WriteAdrMatchM = PreLSURWM[0] & (LSUPAdrM[`PA_BITS-1:2] == ReservationPAdrW) & ReservationValidW;
|
||||||
assign SquashSCM = scM & ~WriteAdrMatchM;
|
assign SquashSCM = scM & ~WriteAdrMatchM;
|
||||||
assign LsuRWM = SquashSCM ? 2'b00 : PreLsuRWM;
|
assign LSURWM = SquashSCM ? 2'b00 : PreLSURWM;
|
||||||
always_comb begin // ReservationValidM (next value of valid reservation)
|
always_comb begin // ReservationValidM (next value of valid reservation)
|
||||||
if (lrM) ReservationValidM = 1; // set valid on load reserve
|
if (lrM) ReservationValidM = 1; // set valid on load reserve
|
||||||
else if (scM | WriteAdrMatchM) ReservationValidM = 0; // clear valid on store to same address or any sc
|
else if (scM | WriteAdrMatchM) ReservationValidM = 0; // clear valid on store to same address or any sc
|
||||||
else ReservationValidM = ReservationValidW; // otherwise don't change valid
|
else ReservationValidM = ReservationValidW; // otherwise don't change valid
|
||||||
end
|
end
|
||||||
flopenrc #(`PA_BITS-2) resadrreg(clk, reset, FlushW, lrM, LsuPAdrM[`PA_BITS-1:2], ReservationPAdrW); // could drop clear on this one but not valid
|
flopenrc #(`PA_BITS-2) resadrreg(clk, reset, FlushW, lrM, LSUPAdrM[`PA_BITS-1:2], ReservationPAdrW); // could drop clear on this one but not valid
|
||||||
flopenrc #(1) resvldreg(clk, reset, FlushW, lrM, ReservationValidM, ReservationValidW);
|
flopenrc #(1) resvldreg(clk, reset, FlushW, lrM, ReservationValidM, ReservationValidW);
|
||||||
flopenrc #(1) squashreg(clk, reset, FlushW, ~CPUBusy, SquashSCM, SquashSCW);
|
flopenrc #(1) squashreg(clk, reset, FlushW, ~CPUBusy, SquashSCM, SquashSCW);
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -63,13 +63,13 @@ module lsu
|
|||||||
output logic StoreMisalignedFaultM, StoreAccessFaultM,
|
output logic StoreMisalignedFaultM, StoreAccessFaultM,
|
||||||
|
|
||||||
// connect to ahb
|
// connect to ahb
|
||||||
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] LsuBusAdr,
|
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] LSUBusAdr,
|
||||||
(* mark_debug = "true" *) output logic LsuBusRead,
|
(* mark_debug = "true" *) output logic LSUBusRead,
|
||||||
(* mark_debug = "true" *) output logic LsuBusWrite,
|
(* mark_debug = "true" *) output logic LSUBusWrite,
|
||||||
(* mark_debug = "true" *) input logic LsuBusAck,
|
(* mark_debug = "true" *) input logic LSUBusAck,
|
||||||
(* mark_debug = "true" *) input logic [`XLEN-1:0] LsuBusHRDATA,
|
(* mark_debug = "true" *) input logic [`XLEN-1:0] LSUBusHRDATA,
|
||||||
(* mark_debug = "true" *) output logic [`XLEN-1:0] LsuBusHWDATA,
|
(* mark_debug = "true" *) output logic [`XLEN-1:0] LSUBusHWDATA,
|
||||||
(* mark_debug = "true" *) output logic [2:0] LsuBusSize,
|
(* mark_debug = "true" *) output logic [2:0] LSUBusSize,
|
||||||
|
|
||||||
// mmu management
|
// mmu management
|
||||||
|
|
||||||
@ -90,17 +90,17 @@ module lsu
|
|||||||
|
|
||||||
logic DTLBPageFaultM;
|
logic DTLBPageFaultM;
|
||||||
|
|
||||||
logic [`PA_BITS-1:0] LsuPAdrM; // from mmu to dcache
|
logic [`PA_BITS-1:0] LSUPAdrM; // from mmu to dcache
|
||||||
logic [`XLEN+1:0] IEUAdrExtM;
|
logic [`XLEN+1:0] IEUAdrExtM;
|
||||||
logic DTLBMissM;
|
logic DTLBMissM;
|
||||||
logic DTLBWriteM;
|
logic DTLBWriteM;
|
||||||
|
|
||||||
logic [1:0] LsuRWM;
|
logic [1:0] LSURWM;
|
||||||
logic [1:0] PreLsuRWM;
|
logic [1:0] PreLSURWM;
|
||||||
logic [2:0] LsuFunct3M;
|
logic [2:0] LSUFunct3M;
|
||||||
logic [1:0] LsuAtomicM;
|
logic [1:0] LSUAtomicM;
|
||||||
(* mark_debug = "true" *) logic [`PA_BITS-1:0] PreLsuPAdrM, LocalLsuBusAdr;
|
(* mark_debug = "true" *) logic [`PA_BITS-1:0] PreLSUPAdrM, LocalLSUBusAdr;
|
||||||
logic [11:0] PreLsuAdrE, LsuAdrE;
|
logic [11:0] PreLSUAdrE, LSUAdrE;
|
||||||
logic CPUBusy;
|
logic CPUBusy;
|
||||||
logic MemReadM;
|
logic MemReadM;
|
||||||
logic DCacheStall;
|
logic DCacheStall;
|
||||||
@ -144,11 +144,11 @@ module lsu
|
|||||||
// arbiter between IEU and hptw
|
// arbiter between IEU and hptw
|
||||||
|
|
||||||
// multiplex the outputs to LSU
|
// multiplex the outputs to LSU
|
||||||
mux2 #(2) rwmux(MemRWM, {HPTWRead, 1'b0}, SelHPTW, PreLsuRWM);
|
mux2 #(2) rwmux(MemRWM, {HPTWRead, 1'b0}, SelHPTW, PreLSURWM);
|
||||||
mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LsuFunct3M);
|
mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LSUFunct3M);
|
||||||
mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LsuAtomicM);
|
mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LSUAtomicM);
|
||||||
mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, PreLsuAdrE);
|
mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, PreLSUAdrE);
|
||||||
mux2 #(`PA_BITS) lsupadrmux(IEUAdrExtM[`PA_BITS-1:0], HPTWAdr, SelHPTW, PreLsuPAdrM);
|
mux2 #(`PA_BITS) lsupadrmux(IEUAdrExtM[`PA_BITS-1:0], HPTWAdr, SelHPTW, PreLSUPAdrM);
|
||||||
|
|
||||||
// always block interrupts when using the hardware page table walker.
|
// always block interrupts when using the hardware page table walker.
|
||||||
assign CPUBusy = StallW & ~SelHPTW;
|
assign CPUBusy = StallW & ~SelHPTW;
|
||||||
@ -158,17 +158,17 @@ module lsu
|
|||||||
//flop #(`PA_BITS) HPTWAdrMReg(clk, HPTWAdr, HPTWAdrM); // delay HPTWAdrM by a cycle
|
//flop #(`PA_BITS) HPTWAdrMReg(clk, HPTWAdr, HPTWAdrM); // delay HPTWAdrM by a cycle
|
||||||
|
|
||||||
// Specify which type of page fault is occurring
|
// Specify which type of page fault is occurring
|
||||||
assign DTLBLoadPageFaultM = DTLBPageFaultM & PreLsuRWM[1];
|
assign DTLBLoadPageFaultM = DTLBPageFaultM & PreLSURWM[1];
|
||||||
assign DTLBStorePageFaultM = DTLBPageFaultM & PreLsuRWM[0];
|
assign DTLBStorePageFaultM = DTLBPageFaultM & PreLSURWM[0];
|
||||||
|
|
||||||
// When replaying CPU memory request after PTW select the IEUAdrM for correct address.
|
// When replaying CPU memory request after PTW select the IEUAdrM for correct address.
|
||||||
assign LsuAdrE = SelReplayCPURequest ? IEUAdrM[11:0] : PreLsuAdrE;
|
assign LSUAdrE = SelReplayCPURequest ? IEUAdrM[11:0] : PreLSUAdrE;
|
||||||
|
|
||||||
end // if (`MEM_VIRTMEM)
|
end // if (`MEM_VIRTMEM)
|
||||||
else begin
|
else begin
|
||||||
assign InterlockStall = 1'b0;
|
assign InterlockStall = 1'b0;
|
||||||
|
|
||||||
assign LsuAdrE = PreLsuAdrE;
|
assign LSUAdrE = PreLSUAdrE;
|
||||||
assign SelHPTW = 1'b0;
|
assign SelHPTW = 1'b0;
|
||||||
assign IgnoreRequest = 1'b0;
|
assign IgnoreRequest = 1'b0;
|
||||||
|
|
||||||
@ -177,11 +177,11 @@ module lsu
|
|||||||
assign DTLBWriteM = 1'b0;
|
assign DTLBWriteM = 1'b0;
|
||||||
assign ITLBWriteF = 1'b0;
|
assign ITLBWriteF = 1'b0;
|
||||||
|
|
||||||
assign PreLsuRWM = MemRWM;
|
assign PreLSURWM = MemRWM;
|
||||||
assign LsuFunct3M = Funct3M;
|
assign LSUFunct3M = Funct3M;
|
||||||
assign LsuAtomicM = AtomicM;
|
assign LSUAtomicM = AtomicM;
|
||||||
assign PreLsuAdrE = IEUAdrE[11:0];
|
assign PreLSUAdrE = IEUAdrE[11:0];
|
||||||
assign PreLsuPAdrM = IEUAdrExtM;
|
assign PreLSUPAdrM = IEUAdrExtM;
|
||||||
assign CPUBusy = StallW;
|
assign CPUBusy = StallW;
|
||||||
|
|
||||||
assign DTLBLoadPageFaultM = 1'b0;
|
assign DTLBLoadPageFaultM = 1'b0;
|
||||||
@ -204,21 +204,21 @@ module lsu
|
|||||||
mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0))
|
mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0))
|
||||||
dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
|
dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
|
||||||
.PrivilegeModeW, .DisableTranslation(SelHPTW),
|
.PrivilegeModeW, .DisableTranslation(SelHPTW),
|
||||||
.PAdr(PreLsuPAdrM),
|
.PAdr(PreLSUPAdrM),
|
||||||
.VAdr(IEUAdrM),
|
.VAdr(IEUAdrM),
|
||||||
.Size(LsuFunct3M[1:0]),
|
.Size(LSUFunct3M[1:0]),
|
||||||
.PTE,
|
.PTE,
|
||||||
.PageTypeWriteVal(PageType),
|
.PageTypeWriteVal(PageType),
|
||||||
.TLBWrite(DTLBWriteM),
|
.TLBWrite(DTLBWriteM),
|
||||||
.TLBFlush(DTLBFlushM),
|
.TLBFlush(DTLBFlushM),
|
||||||
.PhysicalAddress(LsuPAdrM),
|
.PhysicalAddress(LSUPAdrM),
|
||||||
.TLBMiss(DTLBMissM),
|
.TLBMiss(DTLBMissM),
|
||||||
.Cacheable(CacheableM),
|
.Cacheable(CacheableM),
|
||||||
.Idempotent(), .AtomicAllowed(),
|
.Idempotent(), .AtomicAllowed(),
|
||||||
.TLBPageFault(DTLBPageFaultM),
|
.TLBPageFault(DTLBPageFaultM),
|
||||||
.InstrAccessFaultF(), .LoadAccessFaultM, .StoreAccessFaultM,
|
.InstrAccessFaultF(), .LoadAccessFaultM, .StoreAccessFaultM,
|
||||||
.AtomicAccessM(1'b0), .ExecuteAccessF(1'b0), /// atomicaccessm is probably a bug
|
.AtomicAccessM(1'b0), .ExecuteAccessF(1'b0), /// atomicaccessm is probably a bug
|
||||||
.WriteAccessM(PreLsuRWM[0]), .ReadAccessM(PreLsuRWM[1]),
|
.WriteAccessM(PreLSURWM[0]), .ReadAccessM(PreLSURWM[1]),
|
||||||
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW
|
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW
|
||||||
); // *** the pma/pmp instruction access faults don't really matter here. is it possible to parameterize which outputs exist?
|
); // *** the pma/pmp instruction access faults don't really matter here. is it possible to parameterize which outputs exist?
|
||||||
|
|
||||||
@ -237,7 +237,7 @@ module lsu
|
|||||||
assign StoreMisalignedFaultM = DataMisalignedM & MemRWM[0];
|
assign StoreMisalignedFaultM = DataMisalignedM & MemRWM[0];
|
||||||
|
|
||||||
end else begin
|
end else begin
|
||||||
assign LsuPAdrM = PreLsuPAdrM;
|
assign LSUPAdrM = PreLSUPAdrM;
|
||||||
assign DTLBMissM = 0;
|
assign DTLBMissM = 0;
|
||||||
assign CacheableM = 1;
|
assign CacheableM = 1;
|
||||||
assign DTLBPageFaultM = 0;
|
assign DTLBPageFaultM = 0;
|
||||||
@ -249,14 +249,14 @@ module lsu
|
|||||||
assign LSUStall = DCacheStall | InterlockStall | BusStall;
|
assign LSUStall = DCacheStall | InterlockStall | BusStall;
|
||||||
|
|
||||||
|
|
||||||
// use PreLsu as prefix for lrsc
|
// use PreLSU as prefix for lrsc
|
||||||
if (`A_SUPPORTED) begin:lrsc
|
if (`A_SUPPORTED) begin:lrsc
|
||||||
assign MemReadM = PreLsuRWM[1] & ~(IgnoreRequest) & ~DTLBMissM;
|
assign MemReadM = PreLSURWM[1] & ~(IgnoreRequest) & ~DTLBMissM;
|
||||||
lrsc lrsc(.clk, .reset, .FlushW, .CPUBusy, .MemReadM, .PreLsuRWM, .LsuAtomicM, .LsuPAdrM,
|
lrsc lrsc(.clk, .reset, .FlushW, .CPUBusy, .MemReadM, .PreLSURWM, .LSUAtomicM, .LSUPAdrM,
|
||||||
.SquashSCW, .LsuRWM);
|
.SquashSCW, .LSURWM);
|
||||||
end else begin:lrsc
|
end else begin:lrsc
|
||||||
assign SquashSCW = 0;
|
assign SquashSCW = 0;
|
||||||
assign LsuRWM = PreLsuRWM;
|
assign LSURWM = PreLSURWM;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -276,7 +276,7 @@ module lsu
|
|||||||
// temp
|
// temp
|
||||||
|
|
||||||
logic [`XLEN-1:0] FinalAMOWriteDataM, FinalWriteDataM;
|
logic [`XLEN-1:0] FinalAMOWriteDataM, FinalWriteDataM;
|
||||||
(* mark_debug = "true" *) logic [`XLEN-1:0] PreLsuBusHWDATA;
|
(* mark_debug = "true" *) logic [`XLEN-1:0] PreLSUBusHWDATA;
|
||||||
logic [`XLEN-1:0] ReadDataWordM;
|
logic [`XLEN-1:0] ReadDataWordM;
|
||||||
logic [LINELEN-1:0] DCacheMemWriteData;
|
logic [LINELEN-1:0] DCacheMemWriteData;
|
||||||
|
|
||||||
@ -300,8 +300,8 @@ module lsu
|
|||||||
cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN),
|
cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN),
|
||||||
.NUMWAYS(`DCACHE_NUMWAYS), .DCACHE(1))
|
.NUMWAYS(`DCACHE_NUMWAYS), .DCACHE(1))
|
||||||
dcache(.clk, .reset, .CPUBusy,
|
dcache(.clk, .reset, .CPUBusy,
|
||||||
.RW(CacheableM ? LsuRWM : 2'b00), .FlushCache(FlushDCacheM), .Atomic(CacheableM ? LsuAtomicM : 2'b00),
|
.RW(CacheableM ? LSURWM : 2'b00), .FlushCache(FlushDCacheM), .Atomic(CacheableM ? LSUAtomicM : 2'b00),
|
||||||
.NextAdr(LsuAdrE), .PAdr(LsuPAdrM), .NoTranAdr(PreLsuPAdrM[11:0]),
|
.NextAdr(LSUAdrE), .PAdr(LSUPAdrM), .NoTranAdr(PreLSUPAdrM[11:0]),
|
||||||
.FinalWriteData(FinalWriteDataM), .ReadDataWord(ReadDataWordM), .CacheStall(DCacheStall),
|
.FinalWriteData(FinalWriteDataM), .ReadDataWord(ReadDataWordM), .CacheStall(DCacheStall),
|
||||||
.CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess),
|
.CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess),
|
||||||
.IgnoreRequest, .CacheCommitted(DCacheCommittedM),
|
.IgnoreRequest, .CacheCommitted(DCacheCommittedM),
|
||||||
@ -330,23 +330,23 @@ module lsu
|
|||||||
// sub word selection for read and writes and optional amo alu.
|
// sub word selection for read and writes and optional amo alu.
|
||||||
// finally swr
|
// finally swr
|
||||||
subwordread subwordread(.ReadDataWordMuxM,
|
subwordread subwordread(.ReadDataWordMuxM,
|
||||||
.LsuPAdrM(LsuPAdrM[2:0]),
|
.LSUPAdrM(LSUPAdrM[2:0]),
|
||||||
.Funct3M(LsuFunct3M),
|
.Funct3M(LSUFunct3M),
|
||||||
.ReadDataM);
|
.ReadDataM);
|
||||||
|
|
||||||
if (`A_SUPPORTED) begin : amo
|
if (`A_SUPPORTED) begin : amo
|
||||||
logic [`XLEN-1:0] AMOResult;
|
logic [`XLEN-1:0] AMOResult;
|
||||||
amoalu amoalu(.srca(ReadDataM), .srcb(WriteDataM), .funct(Funct7M), .width(LsuFunct3M[1:0]),
|
amoalu amoalu(.srca(ReadDataM), .srcb(WriteDataM), .funct(Funct7M), .width(LSUFunct3M[1:0]),
|
||||||
.result(AMOResult));
|
.result(AMOResult));
|
||||||
mux2 #(`XLEN) wdmux(WriteDataM, AMOResult, LsuAtomicM[1], FinalAMOWriteDataM);
|
mux2 #(`XLEN) wdmux(WriteDataM, AMOResult, LSUAtomicM[1], FinalAMOWriteDataM);
|
||||||
end else
|
end else
|
||||||
assign FinalAMOWriteDataM = WriteDataM;
|
assign FinalAMOWriteDataM = WriteDataM;
|
||||||
|
|
||||||
// this might only get instantiated if there is a dcache or dtim.
|
// this might only get instantiated if there is a dcache or dtim.
|
||||||
// There is a copy in the ebu.
|
// There is a copy in the ebu.
|
||||||
subwordwrite subwordwrite(.HRDATA(ReadDataWordM),
|
subwordwrite subwordwrite(.HRDATA(ReadDataWordM),
|
||||||
.HADDRD(LsuPAdrM[2:0]),
|
.HADDRD(LSUPAdrM[2:0]),
|
||||||
.HSIZED({LsuFunct3M[2], 1'b0, LsuFunct3M[1:0]}),
|
.HSIZED({LSUFunct3M[2], 1'b0, LSUFunct3M[1:0]}),
|
||||||
.HWDATAIN(FinalAMOWriteDataM),
|
.HWDATAIN(FinalAMOWriteDataM),
|
||||||
.HWDATA(FinalWriteDataM));
|
.HWDATA(FinalWriteDataM));
|
||||||
|
|
||||||
@ -359,22 +359,22 @@ module lsu
|
|||||||
genvar index;
|
genvar index;
|
||||||
for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer
|
for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer
|
||||||
flopen #(`XLEN) fb(.clk,
|
flopen #(`XLEN) fb(.clk,
|
||||||
.en(LsuBusAck & LsuBusRead & (index == WordCount)),
|
.en(LSUBusAck & LSUBusRead & (index == WordCount)),
|
||||||
.d(LsuBusHRDATA),
|
.d(LSUBusHRDATA),
|
||||||
.q(DCacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN]));
|
.q(DCacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN]));
|
||||||
end
|
end
|
||||||
|
|
||||||
assign LocalLsuBusAdr = SelUncachedAdr ? LsuPAdrM : DCacheBusAdr ;
|
assign LocalLSUBusAdr = SelUncachedAdr ? LSUPAdrM : DCacheBusAdr ;
|
||||||
assign LsuBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLsuBusAdr;
|
assign LSUBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLSUBusAdr;
|
||||||
assign PreLsuBusHWDATA = ReadDataLineSetsM[WordCount];
|
assign PreLSUBusHWDATA = ReadDataLineSetsM[WordCount];
|
||||||
assign LsuBusHWDATA = SelUncachedAdr ? WriteDataM : PreLsuBusHWDATA; // *** why is this not FinalWriteDataM? which does not work.
|
assign LSUBusHWDATA = SelUncachedAdr ? WriteDataM : PreLSUBusHWDATA; // *** why is this not FinalWriteDataM? which does not work.
|
||||||
|
|
||||||
if (`XLEN == 32) assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b010;
|
if (`XLEN == 32) assign LSUBusSize = SelUncachedAdr ? LSUFunct3M : 3'b010;
|
||||||
else assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b011;
|
else assign LSUBusSize = SelUncachedAdr ? LSUFunct3M : 3'b011;
|
||||||
|
|
||||||
busfsm #(WordCountThreshold, LOGWPL, `MEM_DCACHE)
|
busfsm #(WordCountThreshold, LOGWPL, `MEM_DCACHE)
|
||||||
busfsm(.clk, .reset, .IgnoreRequest, .LsuRWM, .DCacheFetchLine, .DCacheWriteLine,
|
busfsm(.clk, .reset, .IgnoreRequest, .LSURWM, .DCacheFetchLine, .DCacheWriteLine,
|
||||||
.LsuBusAck, .CPUBusy, .CacheableM, .BusStall, .LsuBusWrite, .LsuBusRead,
|
.LSUBusAck, .CPUBusy, .CacheableM, .BusStall, .LSUBusWrite, .LSUBusRead,
|
||||||
.DCacheBusAck, .BusCommittedM, .SelUncachedAdr, .WordCount);
|
.DCacheBusAck, .BusCommittedM, .SelUncachedAdr, .WordCount);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
module subwordread
|
module subwordread
|
||||||
(
|
(
|
||||||
input logic [`XLEN-1:0] ReadDataWordMuxM,
|
input logic [`XLEN-1:0] ReadDataWordMuxM,
|
||||||
input logic [2:0] LsuPAdrM,
|
input logic [2:0] LSUPAdrM,
|
||||||
input logic [2:0] Funct3M,
|
input logic [2:0] Funct3M,
|
||||||
output logic [`XLEN-1:0] ReadDataM
|
output logic [`XLEN-1:0] ReadDataM
|
||||||
);
|
);
|
||||||
@ -41,7 +41,7 @@ module subwordread
|
|||||||
if (`XLEN == 64) begin:swrmux
|
if (`XLEN == 64) begin:swrmux
|
||||||
// ByteMe mux
|
// ByteMe mux
|
||||||
always_comb
|
always_comb
|
||||||
case(LsuPAdrM[2:0])
|
case(LSUPAdrM[2:0])
|
||||||
3'b000: ByteM = ReadDataWordMuxM[7:0];
|
3'b000: ByteM = ReadDataWordMuxM[7:0];
|
||||||
3'b001: ByteM = ReadDataWordMuxM[15:8];
|
3'b001: ByteM = ReadDataWordMuxM[15:8];
|
||||||
3'b010: ByteM = ReadDataWordMuxM[23:16];
|
3'b010: ByteM = ReadDataWordMuxM[23:16];
|
||||||
@ -54,7 +54,7 @@ module subwordread
|
|||||||
|
|
||||||
// halfword mux
|
// halfword mux
|
||||||
always_comb
|
always_comb
|
||||||
case(LsuPAdrM[2:1])
|
case(LSUPAdrM[2:1])
|
||||||
2'b00: HalfwordM = ReadDataWordMuxM[15:0];
|
2'b00: HalfwordM = ReadDataWordMuxM[15:0];
|
||||||
2'b01: HalfwordM = ReadDataWordMuxM[31:16];
|
2'b01: HalfwordM = ReadDataWordMuxM[31:16];
|
||||||
2'b10: HalfwordM = ReadDataWordMuxM[47:32];
|
2'b10: HalfwordM = ReadDataWordMuxM[47:32];
|
||||||
@ -64,7 +64,7 @@ module subwordread
|
|||||||
logic [31:0] WordM;
|
logic [31:0] WordM;
|
||||||
|
|
||||||
always_comb
|
always_comb
|
||||||
case(LsuPAdrM[2])
|
case(LSUPAdrM[2])
|
||||||
1'b0: WordM = ReadDataWordMuxM[31:0];
|
1'b0: WordM = ReadDataWordMuxM[31:0];
|
||||||
1'b1: WordM = ReadDataWordMuxM[63:32];
|
1'b1: WordM = ReadDataWordMuxM[63:32];
|
||||||
endcase
|
endcase
|
||||||
@ -84,7 +84,7 @@ module subwordread
|
|||||||
end else begin:swrmux // 32-bit
|
end else begin:swrmux // 32-bit
|
||||||
// byte mux
|
// byte mux
|
||||||
always_comb
|
always_comb
|
||||||
case(LsuPAdrM[1:0])
|
case(LSUPAdrM[1:0])
|
||||||
2'b00: ByteM = ReadDataWordMuxM[7:0];
|
2'b00: ByteM = ReadDataWordMuxM[7:0];
|
||||||
2'b01: ByteM = ReadDataWordMuxM[15:8];
|
2'b01: ByteM = ReadDataWordMuxM[15:8];
|
||||||
2'b10: ByteM = ReadDataWordMuxM[23:16];
|
2'b10: ByteM = ReadDataWordMuxM[23:16];
|
||||||
@ -93,7 +93,7 @@ module subwordread
|
|||||||
|
|
||||||
// halfword mux
|
// halfword mux
|
||||||
always_comb
|
always_comb
|
||||||
case(LsuPAdrM[1])
|
case(LSUPAdrM[1])
|
||||||
1'b0: HalfwordM = ReadDataWordMuxM[15:0];
|
1'b0: HalfwordM = ReadDataWordMuxM[15:0];
|
||||||
1'b1: HalfwordM = ReadDataWordMuxM[31:16];
|
1'b1: HalfwordM = ReadDataWordMuxM[31:16];
|
||||||
endcase
|
endcase
|
||||||
|
@ -31,16 +31,16 @@ module muldiv (
|
|||||||
// 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 MulDivE, W64E,
|
input logic MDUE, W64E,
|
||||||
// Writeback stage
|
// Writeback stage
|
||||||
output logic [`XLEN-1:0] MulDivResultW,
|
output logic [`XLEN-1:0] MDUResultW,
|
||||||
// Divide Done
|
// Divide Done
|
||||||
output logic DivBusyE,
|
output logic DivBusyE,
|
||||||
// hazards
|
// hazards
|
||||||
input logic StallM, StallW, FlushM, FlushW
|
input logic StallM, StallW, FlushM, FlushW
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [`XLEN-1:0] MulDivResultM;
|
logic [`XLEN-1:0] MDUResultM;
|
||||||
logic [`XLEN-1:0] PrelimResultM;
|
logic [`XLEN-1:0] PrelimResultM;
|
||||||
logic [`XLEN-1:0] QuotM, RemM;
|
logic [`XLEN-1:0] QuotM, RemM;
|
||||||
logic [`XLEN*2-1:0] ProdM;
|
logic [`XLEN*2-1:0] ProdM;
|
||||||
@ -54,7 +54,7 @@ module muldiv (
|
|||||||
|
|
||||||
// Divide
|
// Divide
|
||||||
// Start a divide when a new division instruction is received and the divider isn't already busy or finishing
|
// Start a divide when a new division instruction is received and the divider isn't already busy or finishing
|
||||||
assign DivE = MulDivE & Funct3E[2];
|
assign DivE = MDUE & Funct3E[2];
|
||||||
assign DivSignedE = ~Funct3E[0];
|
assign DivSignedE = ~Funct3E[0];
|
||||||
intdivrestoring div(.clk, .reset, .StallM, .DivSignedE, .W64E, .DivE,
|
intdivrestoring div(.clk, .reset, .StallM, .DivSignedE, .W64E, .DivE,
|
||||||
.ForwardedSrcAE, .ForwardedSrcBE, .DivBusyE, .QuotM, .RemM);
|
.ForwardedSrcAE, .ForwardedSrcBE, .DivBusyE, .QuotM, .RemM);
|
||||||
@ -75,13 +75,13 @@ module muldiv (
|
|||||||
// Handle sign extension for W-type instructions
|
// Handle sign extension for W-type instructions
|
||||||
flopenrc #(1) W64MReg(clk, reset, FlushM, ~StallM, W64E, W64M);
|
flopenrc #(1) W64MReg(clk, reset, FlushM, ~StallM, W64E, W64M);
|
||||||
if (`XLEN == 64) begin:resmux // RV64 has W-type instructions
|
if (`XLEN == 64) begin:resmux // RV64 has W-type instructions
|
||||||
assign MulDivResultM = W64M ? {{32{PrelimResultM[31]}}, PrelimResultM[31:0]} : PrelimResultM;
|
assign MDUResultM = W64M ? {{32{PrelimResultM[31]}}, PrelimResultM[31:0]} : PrelimResultM;
|
||||||
end else begin:resmux // RV32 has no W-type instructions
|
end else begin:resmux // RV32 has no W-type instructions
|
||||||
assign MulDivResultM = PrelimResultM;
|
assign MDUResultM = PrelimResultM;
|
||||||
end
|
end
|
||||||
|
|
||||||
// Writeback stage pipeline register
|
// Writeback stage pipeline register
|
||||||
flopenrc #(`XLEN) MulDivResultWReg(clk, reset, FlushW, ~StallW, MulDivResultM, MulDivResultW);
|
flopenrc #(`XLEN) MDUResultWReg(clk, reset, FlushW, ~StallW, MDUResultM, MDUResultW);
|
||||||
endmodule // muldiv
|
endmodule // muldiv
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ module wallypipelinedhart (
|
|||||||
(* 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 MulDivE, W64E;
|
logic MDUE, W64E;
|
||||||
logic CSRReadM, CSRWriteM, PrivilegedM;
|
logic CSRReadM, CSRWriteM, PrivilegedM;
|
||||||
logic [1:0] AtomicE;
|
logic [1:0] AtomicE;
|
||||||
logic [1:0] AtomicM;
|
logic [1:0] AtomicM;
|
||||||
@ -68,7 +68,7 @@ module wallypipelinedhart (
|
|||||||
(* mark_debug = "true" *) logic [31:0] InstrM;
|
(* mark_debug = "true" *) logic [31:0] InstrM;
|
||||||
logic [`XLEN-1:0] PCF, PCD, PCE, PCLinkE;
|
logic [`XLEN-1:0] PCF, PCD, PCE, PCLinkE;
|
||||||
(* mark_debug = "true" *) logic [`XLEN-1:0] PCM;
|
(* mark_debug = "true" *) logic [`XLEN-1:0] PCM;
|
||||||
logic [`XLEN-1:0] CSRReadValW, MulDivResultW;
|
logic [`XLEN-1:0] CSRReadValW, MDUResultW;
|
||||||
logic [`XLEN-1:0] PrivilegedNextPCM;
|
logic [`XLEN-1:0] PrivilegedNextPCM;
|
||||||
(* mark_debug = "true" *) logic [1:0] MemRWM;
|
(* mark_debug = "true" *) logic [1:0] MemRWM;
|
||||||
(* mark_debug = "true" *) logic InstrValidM;
|
(* mark_debug = "true" *) logic InstrValidM;
|
||||||
@ -82,7 +82,7 @@ module wallypipelinedhart (
|
|||||||
logic PCSrcE;
|
logic PCSrcE;
|
||||||
logic CSRWritePendingDEM;
|
logic CSRWritePendingDEM;
|
||||||
logic DivBusyE;
|
logic DivBusyE;
|
||||||
logic LoadStallD, StoreStallD, MulDivStallD, CSRRdStallD;
|
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
|
||||||
logic SquashSCW;
|
logic SquashSCW;
|
||||||
// floating point unit signals
|
// floating point unit signals
|
||||||
logic [2:0] FRM_REGW;
|
logic [2:0] FRM_REGW;
|
||||||
@ -113,7 +113,7 @@ module wallypipelinedhart (
|
|||||||
var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0];
|
var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0];
|
||||||
|
|
||||||
// IMem stalls
|
// IMem stalls
|
||||||
logic IfuStallF;
|
logic IFUStallF;
|
||||||
logic LSUStall;
|
logic LSUStall;
|
||||||
|
|
||||||
|
|
||||||
@ -128,18 +128,18 @@ module wallypipelinedhart (
|
|||||||
logic CommittedM;
|
logic CommittedM;
|
||||||
|
|
||||||
// AHB ifu interface
|
// AHB ifu interface
|
||||||
logic [`PA_BITS-1:0] IfuBusAdr;
|
logic [`PA_BITS-1:0] IFUBusAdr;
|
||||||
logic [`XLEN-1:0] IfuBusHRDATA;
|
logic [`XLEN-1:0] IFUBusHRDATA;
|
||||||
logic IfuBusRead;
|
logic IFUBusRead;
|
||||||
logic IfuBusAck;
|
logic IFUBusAck;
|
||||||
|
|
||||||
// AHB LSU interface
|
// AHB LSU interface
|
||||||
logic [`PA_BITS-1:0] LsuBusAdr;
|
logic [`PA_BITS-1:0] LSUBusAdr;
|
||||||
logic LsuBusRead;
|
logic LSUBusRead;
|
||||||
logic LsuBusWrite;
|
logic LSUBusWrite;
|
||||||
logic LsuBusAck;
|
logic LSUBusAck;
|
||||||
logic [`XLEN-1:0] LsuBusHRDATA;
|
logic [`XLEN-1:0] LSUBusHRDATA;
|
||||||
logic [`XLEN-1:0] LsuBusHWDATA;
|
logic [`XLEN-1:0] LSUBusHWDATA;
|
||||||
|
|
||||||
logic BPPredWrongE;
|
logic BPPredWrongE;
|
||||||
logic BPPredDirWrongM;
|
logic BPPredDirWrongM;
|
||||||
@ -148,7 +148,7 @@ module wallypipelinedhart (
|
|||||||
logic BPPredClassNonCFIWrongM;
|
logic BPPredClassNonCFIWrongM;
|
||||||
logic [4:0] InstrClassM;
|
logic [4:0] InstrClassM;
|
||||||
logic InstrAccessFaultF;
|
logic InstrAccessFaultF;
|
||||||
logic [2:0] LsuBusSize;
|
logic [2:0] LSUBusSize;
|
||||||
|
|
||||||
logic ExceptionM;
|
logic ExceptionM;
|
||||||
logic PendingInterruptM;
|
logic PendingInterruptM;
|
||||||
@ -164,8 +164,8 @@ module wallypipelinedhart (
|
|||||||
|
|
||||||
.ExceptionM, .PendingInterruptM,
|
.ExceptionM, .PendingInterruptM,
|
||||||
// Fetch
|
// Fetch
|
||||||
.IfuBusHRDATA, .IfuBusAck, .PCF, .IfuBusAdr,
|
.IFUBusHRDATA, .IFUBusAck, .PCF, .IFUBusAdr,
|
||||||
.IfuBusRead, .IfuStallF,
|
.IFUBusRead, .IFUStallF,
|
||||||
|
|
||||||
// Execute
|
// Execute
|
||||||
.PCLinkE, .PCSrcE, .IEUAdrE, .PCE,
|
.PCLinkE, .PCSrcE, .IEUAdrE, .PCE,
|
||||||
@ -206,7 +206,7 @@ module wallypipelinedhart (
|
|||||||
|
|
||||||
// Execute Stage interface
|
// Execute Stage interface
|
||||||
.PCE, .PCLinkE, .FWriteIntE, .IllegalFPUInstrE,
|
.PCE, .PCLinkE, .FWriteIntE, .IllegalFPUInstrE,
|
||||||
.FWriteDataE, .IEUAdrE, .MulDivE, .W64E,
|
.FWriteDataE, .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
|
||||||
|
|
||||||
// Memory stage interface
|
// Memory stage interface
|
||||||
@ -220,14 +220,14 @@ module wallypipelinedhart (
|
|||||||
.RdM, .FIntResM, .InvalidateICacheM, .FlushDCacheM,
|
.RdM, .FIntResM, .InvalidateICacheM, .FlushDCacheM,
|
||||||
|
|
||||||
// Writeback stage
|
// Writeback stage
|
||||||
.CSRReadValW, .ReadDataM, .MulDivResultW,
|
.CSRReadValW, .ReadDataM, .MDUResultW,
|
||||||
.RdW, .ReadDataW,
|
.RdW, .ReadDataW,
|
||||||
.InstrValidM,
|
.InstrValidM,
|
||||||
|
|
||||||
// hazards
|
// hazards
|
||||||
.StallD, .StallE, .StallM, .StallW,
|
.StallD, .StallE, .StallM, .StallW,
|
||||||
.FlushD, .FlushE, .FlushM, .FlushW,
|
.FlushD, .FlushE, .FlushM, .FlushW,
|
||||||
.FPUStallD, .LoadStallD, .MulDivStallD, .CSRRdStallD,
|
.FPUStallD, .LoadStallD, .MDUStallD, .CSRRdStallD,
|
||||||
.PCSrcE,
|
.PCSrcE,
|
||||||
.CSRReadM, .CSRWriteM, .PrivilegedM,
|
.CSRReadM, .CSRWriteM, .PrivilegedM,
|
||||||
.CSRWritePendingDEM, .StoreStallD
|
.CSRWritePendingDEM, .StoreStallD
|
||||||
@ -246,8 +246,8 @@ module wallypipelinedhart (
|
|||||||
.IEUAdrE, .IEUAdrM, .WriteDataM,
|
.IEUAdrE, .IEUAdrM, .WriteDataM,
|
||||||
.ReadDataM, .FlushDCacheM,
|
.ReadDataM, .FlushDCacheM,
|
||||||
// connected to ahb (all stay the same)
|
// connected to ahb (all stay the same)
|
||||||
.LsuBusAdr, .LsuBusRead, .LsuBusWrite, .LsuBusAck,
|
.LSUBusAdr, .LSUBusRead, .LSUBusWrite, .LSUBusAck,
|
||||||
.LsuBusHRDATA, .LsuBusHWDATA, .LsuBusSize,
|
.LSUBusHRDATA, .LSUBusHWDATA, .LSUBusSize,
|
||||||
|
|
||||||
// connect to csr or privilege and stay the same.
|
// connect to csr or privilege and stay the same.
|
||||||
.PrivilegeModeW, // connects to csr
|
.PrivilegeModeW, // connects to csr
|
||||||
@ -277,13 +277,13 @@ module wallypipelinedhart (
|
|||||||
ahblite ebu(// IFU connections
|
ahblite ebu(// IFU connections
|
||||||
.clk, .reset,
|
.clk, .reset,
|
||||||
.UnsignedLoadM(1'b0), .AtomicMaskedM(2'b00),
|
.UnsignedLoadM(1'b0), .AtomicMaskedM(2'b00),
|
||||||
.IfuBusAdr,
|
.IFUBusAdr,
|
||||||
.IfuBusRead, .IfuBusHRDATA, .IfuBusAck,
|
.IFUBusRead, .IFUBusHRDATA, .IFUBusAck,
|
||||||
// Signals from Data Cache
|
// Signals from Data Cache
|
||||||
.LsuBusAdr, .LsuBusRead, .LsuBusWrite, .LsuBusHWDATA,
|
.LSUBusAdr, .LSUBusRead, .LSUBusWrite, .LSUBusHWDATA,
|
||||||
.LsuBusHRDATA,
|
.LSUBusHRDATA,
|
||||||
.LsuBusSize,
|
.LSUBusSize,
|
||||||
.LsuBusAck,
|
.LSUBusAck,
|
||||||
|
|
||||||
.HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn,
|
.HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn,
|
||||||
.HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST,
|
.HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST,
|
||||||
@ -293,8 +293,8 @@ module wallypipelinedhart (
|
|||||||
|
|
||||||
hazard hzu(
|
hazard hzu(
|
||||||
.BPPredWrongE, .CSRWritePendingDEM, .RetM, .TrapM,
|
.BPPredWrongE, .CSRWritePendingDEM, .RetM, .TrapM,
|
||||||
.LoadStallD, .StoreStallD, .MulDivStallD, .CSRRdStallD,
|
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD,
|
||||||
.LSUStall, .IfuStallF,
|
.LSUStall, .IFUStallF,
|
||||||
.FPUStallD, .FStallD,
|
.FPUStallD, .FStallD,
|
||||||
.DivBusyE, .FDivBusyE,
|
.DivBusyE, .FDivBusyE,
|
||||||
.EcallFaultM, .BreakpointFaultM,
|
.EcallFaultM, .BreakpointFaultM,
|
||||||
@ -347,12 +347,12 @@ module wallypipelinedhart (
|
|||||||
muldiv mdu(
|
muldiv mdu(
|
||||||
.clk, .reset,
|
.clk, .reset,
|
||||||
.ForwardedSrcAE, .ForwardedSrcBE,
|
.ForwardedSrcAE, .ForwardedSrcBE,
|
||||||
.Funct3E, .Funct3M, .MulDivE, .W64E,
|
.Funct3E, .Funct3M, .MDUE, .W64E,
|
||||||
.MulDivResultW, .DivBusyE,
|
.MDUResultW, .DivBusyE,
|
||||||
.StallM, .StallW, .FlushM, .FlushW
|
.StallM, .StallW, .FlushM, .FlushW
|
||||||
);
|
);
|
||||||
end else begin // no M instructions supported
|
end else begin // no M instructions supported
|
||||||
assign MulDivResultW = 0;
|
assign MDUResultW = 0;
|
||||||
assign DivBusyE = 0;
|
assign DivBusyE = 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -438,7 +438,7 @@ module testbench;
|
|||||||
end \
|
end \
|
||||||
if(`"STAGE`"=="M") begin \
|
if(`"STAGE`"=="M") begin \
|
||||||
// override on special conditions \
|
// override on special conditions \
|
||||||
if (dut.hart.lsu.LsuPAdrM == 'h10000005) \
|
if (dut.hart.lsu.LSUPAdrM == 'h10000005) \
|
||||||
//$display("%tns, %d instrs: Overwrite UART's LSR in memory stage.", $time, InstrCountW-1); \
|
//$display("%tns, %d instrs: Overwrite UART's LSR in memory stage.", $time, InstrCountW-1); \
|
||||||
force dut.hart.ieu.dp.ReadDataM = ExpectedMemReadDataM; \
|
force dut.hart.ieu.dp.ReadDataM = ExpectedMemReadDataM; \
|
||||||
else \
|
else \
|
||||||
|
Loading…
Reference in New Issue
Block a user