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
0e023e29d8
commit
1d8451c2cf
@ -40,18 +40,18 @@ module ahblite (
|
||||
input logic UnsignedLoadM,
|
||||
input logic [1:0] AtomicMaskedM,
|
||||
// Signals from Instruction Cache
|
||||
input logic [`PA_BITS-1:0] IfuBusAdr,
|
||||
input logic IfuBusRead,
|
||||
output logic [`XLEN-1:0] IfuBusHRDATA,
|
||||
output logic IfuBusAck,
|
||||
input logic [`PA_BITS-1:0] IFUBusAdr,
|
||||
input logic IFUBusRead,
|
||||
output logic [`XLEN-1:0] IFUBusHRDATA,
|
||||
output logic IFUBusAck,
|
||||
// Signals from Data Cache
|
||||
input logic [`PA_BITS-1:0] LsuBusAdr,
|
||||
input logic LsuBusRead,
|
||||
input logic LsuBusWrite,
|
||||
input logic [`XLEN-1:0] LsuBusHWDATA,
|
||||
output logic [`XLEN-1:0] LsuBusHRDATA,
|
||||
input logic [2:0] LsuBusSize,
|
||||
output logic LsuBusAck,
|
||||
input logic [`PA_BITS-1:0] LSUBusAdr,
|
||||
input logic LSUBusRead,
|
||||
input logic LSUBusWrite,
|
||||
input logic [`XLEN-1:0] LSUBusHWDATA,
|
||||
output logic [`XLEN-1:0] LSUBusHRDATA,
|
||||
input logic [2:0] LSUBusSize,
|
||||
output logic LSUBusAck,
|
||||
// AHB-Lite external signals
|
||||
(* mark_debug = "true" *) input logic [`AHBW-1:0] HRDATA,
|
||||
(* mark_debug = "true" *) input logic HREADY, HRESP,
|
||||
@ -98,35 +98,35 @@ module ahblite (
|
||||
// interface that might be used in place of the ahblite.
|
||||
always_comb
|
||||
case (BusState)
|
||||
IDLE: if (LsuBusRead) NextBusState = MEMREAD; // Memory has priority over instructions
|
||||
else if (LsuBusWrite)NextBusState = MEMWRITE;
|
||||
else if (IfuBusRead) NextBusState = INSTRREAD;
|
||||
IDLE: if (LSUBusRead) NextBusState = MEMREAD; // Memory has priority over instructions
|
||||
else if (LSUBusWrite)NextBusState = MEMWRITE;
|
||||
else if (IFUBusRead) NextBusState = INSTRREAD;
|
||||
else NextBusState = IDLE;
|
||||
MEMREAD: if (~HREADY) NextBusState = MEMREAD;
|
||||
else if (IfuBusRead) NextBusState = INSTRREAD;
|
||||
else if (IFUBusRead) NextBusState = INSTRREAD;
|
||||
else NextBusState = IDLE;
|
||||
MEMWRITE: if (~HREADY) NextBusState = MEMWRITE;
|
||||
else if (IfuBusRead) NextBusState = INSTRREAD;
|
||||
else if (IFUBusRead) NextBusState = INSTRREAD;
|
||||
else NextBusState = IDLE;
|
||||
INSTRREAD: if (~HREADY) NextBusState = INSTRREAD;
|
||||
else NextBusState = IDLE; // if (IfuBusRead still high)
|
||||
else NextBusState = IDLE; // if (IFUBusRead still high)
|
||||
default: NextBusState = IDLE;
|
||||
endcase
|
||||
|
||||
|
||||
// bus outputs
|
||||
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 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 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 HMASTLOCK = 0; // no locking supported
|
||||
assign HWRITE = NextBusState == MEMWRITE;
|
||||
// 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
|
||||
flop #(3) adrreg(HCLK, HADDR[2:0], HADDRD);
|
||||
flop #(4) sizereg(HCLK, {UnsignedLoadM, HSIZE}, HSIZED);
|
||||
@ -136,9 +136,9 @@ module ahblite (
|
||||
// *** assumes AHBW = XLEN
|
||||
|
||||
|
||||
assign IfuBusHRDATA = HRDATA;
|
||||
assign LsuBusHRDATA = HRDATA;
|
||||
assign IfuBusAck = (BusState == INSTRREAD) & (NextBusState != INSTRREAD);
|
||||
assign LsuBusAck = (BusState == MEMREAD) & (NextBusState != MEMREAD) | (BusState == MEMWRITE) & (NextBusState != MEMWRITE);
|
||||
assign IFUBusHRDATA = HRDATA;
|
||||
assign LSUBusHRDATA = HRDATA;
|
||||
assign IFUBusAck = (BusState == INSTRREAD) & (NextBusState != INSTRREAD);
|
||||
assign LSUBusAck = (BusState == MEMREAD) & (NextBusState != MEMREAD) | (BusState == MEMWRITE) & (NextBusState != MEMWRITE);
|
||||
|
||||
endmodule
|
||||
|
@ -28,8 +28,8 @@
|
||||
module hazard(
|
||||
// Detect hazards
|
||||
(* mark_debug = "true" *) input logic BPPredWrongE, CSRWritePendingDEM, RetM, TrapM,
|
||||
(* mark_debug = "true" *) input logic LoadStallD, StoreStallD, MulDivStallD, CSRRdStallD,
|
||||
(* mark_debug = "true" *) input logic LSUStall, IfuStallF,
|
||||
(* mark_debug = "true" *) input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD,
|
||||
(* mark_debug = "true" *) input logic LSUStall, IFUStallF,
|
||||
(* mark_debug = "true" *) input logic FPUStallD, FStallD,
|
||||
(* mark_debug = "true" *) input logic DivBusyE,FDivBusyE,
|
||||
(* 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.
|
||||
|
||||
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 StallMCause = 0;
|
||||
assign StallWCause = LSUStall | IfuStallF;
|
||||
assign StallWCause = LSUStall | IFUStallF;
|
||||
|
||||
assign StallF = StallFCause | StallD;
|
||||
assign StallD = StallDCause | StallE;
|
||||
|
@ -44,7 +44,7 @@ module controller(
|
||||
output logic ALUResultSrcE,
|
||||
output logic MemReadE, CSRReadE, // for Hazard Unit
|
||||
output logic [2:0] Funct3E,
|
||||
output logic MulDivE, W64E,
|
||||
output logic MDUE, W64E,
|
||||
output logic JumpE,
|
||||
// Memory stage control signals
|
||||
input logic StallM, FlushM,
|
||||
@ -83,7 +83,7 @@ module controller(
|
||||
logic ALUOpD;
|
||||
logic [2:0] ALUControlD;
|
||||
logic ALUSrcAD, ALUSrcBD;
|
||||
logic ALUResultSrcD, W64D, MulDivD;
|
||||
logic ALUResultSrcD, W64D, MDUD;
|
||||
logic CSRZeroSrcD;
|
||||
logic CSRReadD;
|
||||
logic [1:0] AtomicD;
|
||||
@ -111,7 +111,7 @@ module controller(
|
||||
// Main Instruction Decoder
|
||||
always_comb
|
||||
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'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
|
||||
@ -162,7 +162,7 @@ module controller(
|
||||
assign IllegalBaseInstrFaultD = ControlsD[0];
|
||||
assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD,
|
||||
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
|
||||
|
||||
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
|
||||
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},
|
||||
{IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE});
|
||||
{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, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE});
|
||||
|
||||
// Branch Logic
|
||||
assign {eqE, ltE, ltuE} = FlagsE;
|
||||
|
@ -58,7 +58,7 @@ module datapath (
|
||||
input logic [2:0] ResultSrcW,
|
||||
output logic [`XLEN-1:0] ReadDataW,
|
||||
// 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
|
||||
output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E,
|
||||
output logic [4:0] RdE, RdM, RdW
|
||||
@ -121,7 +121,7 @@ module datapath (
|
||||
flopenrc #(`XLEN) ResultWReg(clk, reset, FlushW, ~StallW, ResultM, ResultW);
|
||||
flopenrc #(5) RdWReg(clk, reset, FlushW, ~StallW, RdM, RdW);
|
||||
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
|
||||
if (`F_SUPPORTED) begin:fpmux
|
||||
|
@ -28,13 +28,13 @@
|
||||
module forward(
|
||||
// Detect hazards
|
||||
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 FWriteIntE,
|
||||
input logic SCE,
|
||||
// Forwarding controls
|
||||
output logic [1:0] ForwardAE, ForwardBE,
|
||||
output logic FPUStallD, LoadStallD, MulDivStallD, CSRRdStallD
|
||||
output logic FPUStallD, LoadStallD, MDUStallD, CSRRdStallD
|
||||
);
|
||||
|
||||
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 FPUStallD = FWriteIntE & MatchDE;
|
||||
assign LoadStallD = (MemReadE|SCE) & MatchDE;
|
||||
assign MulDivStallD = MulDivE & MatchDE;
|
||||
assign MDUStallD = MDUE & MatchDE;
|
||||
assign CSRRdStallD = CSRReadE & MatchDE;
|
||||
endmodule
|
||||
|
@ -38,7 +38,7 @@ module ieu (
|
||||
input logic IllegalFPUInstrE,
|
||||
input logic [`XLEN-1:0] FWriteDataE,
|
||||
output logic [`XLEN-1:0] IEUAdrE,
|
||||
output logic MulDivE, W64E,
|
||||
output logic MDUE, W64E,
|
||||
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
|
||||
|
||||
@ -56,7 +56,7 @@ module ieu (
|
||||
output logic InvalidateICacheM, FlushDCacheM,
|
||||
|
||||
// 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 [`XLEN-1:0] ReadDataW,
|
||||
// input logic [`XLEN-1:0] PCLinkW,
|
||||
@ -64,7 +64,7 @@ module ieu (
|
||||
// hazards
|
||||
input logic StallD, StallE, StallM, StallW,
|
||||
input logic FlushD, FlushE, FlushM, FlushW,
|
||||
output logic FPUStallD, LoadStallD, MulDivStallD, CSRRdStallD,
|
||||
output logic FPUStallD, LoadStallD, MDUStallD, CSRRdStallD,
|
||||
output logic PCSrcE,
|
||||
output logic CSRReadM, CSRWriteM, PrivilegedM,
|
||||
output logic CSRWritePendingDEM,
|
||||
@ -92,7 +92,7 @@ module ieu (
|
||||
.clk, .reset, .StallD, .FlushD, .InstrD, .ImmSrcD,
|
||||
.IllegalIEUInstrFaultD, .IllegalBaseInstrFaultD, .StallE, .FlushE, .FlagsE, .FWriteIntE,
|
||||
.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,
|
||||
.RegWriteM, .InvalidateICacheM, .FlushDCacheM, .InstrValidM, .FWriteIntM,
|
||||
.StallW, .FlushW, .RegWriteW, .ResultSrcW, .CSRWritePendingDEM, .StoreStallD);
|
||||
@ -103,12 +103,12 @@ module ieu (
|
||||
.FWriteDataE, .PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE,
|
||||
.StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM,
|
||||
.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(
|
||||
.Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW,
|
||||
.MemReadE, .MulDivE, .CSRReadE, .RegWriteM, .RegWriteW,
|
||||
.MemReadE, .MDUE, .CSRReadE, .RegWriteM, .RegWriteW,
|
||||
.FWriteIntE, .SCE, .ForwardAE, .ForwardBE,
|
||||
.FPUStallD, .LoadStallD, .MulDivStallD, .CSRRdStallD);
|
||||
.FPUStallD, .LoadStallD, .MDUStallD, .CSRRdStallD);
|
||||
endmodule
|
||||
|
||||
|
@ -31,11 +31,11 @@ module ifu (
|
||||
input logic StallF, StallD, StallE, StallM, StallW,
|
||||
input logic FlushF, FlushD, FlushE, FlushM, FlushW,
|
||||
// Bus interface
|
||||
(* mark_debug = "true" *) input logic [`XLEN-1:0] IfuBusHRDATA,
|
||||
(* mark_debug = "true" *) input logic IfuBusAck,
|
||||
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] IfuBusAdr,
|
||||
(* mark_debug = "true" *) output logic IfuBusRead,
|
||||
(* mark_debug = "true" *) output logic IfuStallF,
|
||||
(* mark_debug = "true" *) input logic [`XLEN-1:0] IFUBusHRDATA,
|
||||
(* mark_debug = "true" *) input logic IFUBusAck,
|
||||
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] IFUBusAdr,
|
||||
(* mark_debug = "true" *) output logic IFUBusRead,
|
||||
(* mark_debug = "true" *) output logic IFUStallF,
|
||||
(* mark_debug = "true" *) output logic [`XLEN-1:0] PCF,
|
||||
// Execute
|
||||
output logic [`XLEN-1:0] PCLinkE,
|
||||
@ -210,8 +210,8 @@ module ifu (
|
||||
|
||||
// *** put memory interface on here, InstrF becomes output
|
||||
//assign ICacheBusAdr = PCF; // *** no MMU
|
||||
//assign IfuBusFetch = ~StallD; // *** & ICacheMissF; add later
|
||||
// assign IfuBusFetch = 1; // *** & ICacheMissF; add later
|
||||
//assign IFUBusFetch = ~StallD; // *** & ICacheMissF; add later
|
||||
// assign IFUBusFetch = 1; // *** & ICacheMissF; add later
|
||||
|
||||
// conditional
|
||||
// 1. ram // controlled by `MEM_IROM
|
||||
@ -229,13 +229,13 @@ module ifu (
|
||||
logic [LOGWPL-1:0] WordCount;
|
||||
logic [LINELEN-1:0] ICacheMemWriteData;
|
||||
logic ICacheBusAck;
|
||||
logic [`PA_BITS-1:0] LocalIfuBusAdr;
|
||||
logic [`PA_BITS-1:0] LocalIFUBusAdr;
|
||||
logic [`PA_BITS-1:0] ICacheBusAdr;
|
||||
logic SelUncachedAdr;
|
||||
|
||||
if(`MEM_ICACHE) begin : icache
|
||||
logic [1:0] IfuRWF;
|
||||
assign IfuRWF = CacheableF ? 2'b10 : 2'b00;
|
||||
logic [1:0] IFURWF;
|
||||
assign IFURWF = CacheableF ? 2'b10 : 2'b00;
|
||||
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
icache #(.LINELEN(`ICACHE_LINELENINBITS),
|
||||
@ -244,7 +244,7 @@ module ifu (
|
||||
icache(.clk, .reset, .CPUBusy, .IgnoreRequest, .ICacheMemWriteData , .ICacheBusAck,
|
||||
.ICacheBusAdr, .ICacheStallF, .FinalInstrRawF,
|
||||
.ICacheFetchLine,
|
||||
.IfuRWF(IfuRWF), //aways read
|
||||
.IFURWF(IFURWF), //aways read
|
||||
.PCNextF(PCNextFMux),
|
||||
.PCPF(PCPF),
|
||||
.PCF(PCFMux),
|
||||
@ -264,7 +264,7 @@ module ifu (
|
||||
.CacheMiss(),
|
||||
.CacheAccess(),
|
||||
.FinalWriteData('0),
|
||||
.RW(IfuRWF),
|
||||
.RW(IFURWF),
|
||||
.Atomic(2'b00),
|
||||
.FlushCache(1'b0),
|
||||
.NextAdr(PCNextFMux),
|
||||
@ -293,23 +293,23 @@ module ifu (
|
||||
genvar index;
|
||||
for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer
|
||||
flopen #(`XLEN) fb(.clk(clk),
|
||||
.en(IfuBusAck & IfuBusRead & (index == WordCount)),
|
||||
.d(IfuBusHRDATA),
|
||||
.en(IFUBusAck & IFUBusRead & (index == WordCount)),
|
||||
.d(IFUBusHRDATA),
|
||||
.q(ICacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN]));
|
||||
end
|
||||
|
||||
assign LocalIfuBusAdr = SelUncachedAdr ? PCPF : ICacheBusAdr;
|
||||
assign IfuBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalIfuBusAdr;
|
||||
assign LocalIFUBusAdr = SelUncachedAdr ? PCPF : ICacheBusAdr;
|
||||
assign IFUBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalIFUBusAdr;
|
||||
|
||||
busfsm #(WordCountThreshold, LOGWPL, `MEM_ICACHE)
|
||||
busfsm(.clk, .reset, .IgnoreRequest,
|
||||
.LsuRWM(2'b10), .DCacheFetchLine(ICacheFetchLine), .DCacheWriteLine(1'b0),
|
||||
.LsuBusAck(IfuBusAck),
|
||||
.LSURWM(2'b10), .DCacheFetchLine(ICacheFetchLine), .DCacheWriteLine(1'b0),
|
||||
.LSUBusAck(IFUBusAck),
|
||||
.CPUBusy, .CacheableM(CacheableF),
|
||||
.BusStall, .LsuBusWrite(), .LsuBusRead(IfuBusRead), .DCacheBusAck(ICacheBusAck),
|
||||
.BusStall, .LSUBusWrite(), .LSUBusRead(IFUBusRead), .DCacheBusAck(ICacheBusAck),
|
||||
.BusCommittedM(), .SelUncachedAdr(SelUncachedAdr), .WordCount);
|
||||
|
||||
assign IfuStallF = ICacheStallF | BusStall | SelNextSpill;
|
||||
assign IFUStallF = ICacheStallF | BusStall | SelNextSpill;
|
||||
assign CPUBusy = StallF & ~SelNextSpill;
|
||||
|
||||
//assign IgnoreRequest = ITLBMissF | ExceptionM | PendingInterruptM;
|
||||
|
@ -32,16 +32,16 @@ module busfsm #(parameter integer WordCountThreshold,
|
||||
input logic reset,
|
||||
|
||||
input logic IgnoreRequest,
|
||||
input logic [1:0] LsuRWM,
|
||||
input logic [1:0] LSURWM,
|
||||
input logic DCacheFetchLine,
|
||||
input logic DCacheWriteLine,
|
||||
input logic LsuBusAck,
|
||||
input logic LSUBusAck,
|
||||
input logic CPUBusy,
|
||||
input logic CacheableM,
|
||||
|
||||
output logic BusStall,
|
||||
output logic LsuBusWrite,
|
||||
output logic LsuBusRead,
|
||||
output logic LSUBusWrite,
|
||||
output logic LSUBusRead,
|
||||
output logic DCacheBusAck,
|
||||
output logic BusCommittedM,
|
||||
output logic SelUncachedAdr,
|
||||
@ -49,8 +49,8 @@ module busfsm #(parameter integer WordCountThreshold,
|
||||
|
||||
|
||||
|
||||
logic UnCachedLsuBusRead;
|
||||
logic UnCachedLsuBusWrite;
|
||||
logic UnCachedLSUBusRead;
|
||||
logic UnCachedLSUBusWrite;
|
||||
logic CntEn, PreCntEn;
|
||||
logic CntReset;
|
||||
logic WordCountFlag;
|
||||
@ -80,7 +80,7 @@ module busfsm #(parameter integer WordCountThreshold,
|
||||
assign NextWordCount = WordCount + 1'b1;
|
||||
|
||||
assign WordCountFlag = (WordCount == WordCountThreshold[LOGWPL-1:0]);
|
||||
assign CntEn = PreCntEn & LsuBusAck;
|
||||
assign CntEn = PreCntEn & LSUBusAck;
|
||||
|
||||
assign UnCachedAccess = ~CacheEnabled | ~CacheableM;
|
||||
|
||||
@ -91,14 +91,14 @@ module busfsm #(parameter integer WordCountThreshold,
|
||||
always_comb begin
|
||||
case(BusCurrState)
|
||||
STATE_BUS_READY: if(IgnoreRequest) BusNextState = STATE_BUS_READY;
|
||||
else if(LsuRWM[0] & (UnCachedAccess)) BusNextState = STATE_BUS_UNCACHED_WRITE;
|
||||
else if(LsuRWM[1] & (UnCachedAccess)) BusNextState = STATE_BUS_UNCACHED_READ;
|
||||
else if(LSURWM[0] & (UnCachedAccess)) BusNextState = STATE_BUS_UNCACHED_WRITE;
|
||||
else if(LSURWM[1] & (UnCachedAccess)) BusNextState = STATE_BUS_UNCACHED_READ;
|
||||
else if(DCacheFetchLine) BusNextState = STATE_BUS_FETCH;
|
||||
else if(DCacheWriteLine) BusNextState = STATE_BUS_WRITE;
|
||||
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;
|
||||
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;
|
||||
STATE_BUS_UNCACHED_WRITE_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY;
|
||||
else BusNextState = STATE_BUS_READY;
|
||||
@ -106,9 +106,9 @@ module busfsm #(parameter integer WordCountThreshold,
|
||||
else BusNextState = STATE_BUS_READY;
|
||||
STATE_BUS_CPU_BUSY: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY;
|
||||
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;
|
||||
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;
|
||||
default: BusNextState = STATE_BUS_READY;
|
||||
endcase
|
||||
@ -116,24 +116,24 @@ module busfsm #(parameter integer WordCountThreshold,
|
||||
|
||||
|
||||
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_READ) |
|
||||
(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);
|
||||
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);
|
||||
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) |
|
||||
(BusCurrState == STATE_BUS_WRITE & WordCountFlag & LsuBusAck);
|
||||
assign DCacheBusAck = (BusCurrState == STATE_BUS_FETCH & WordCountFlag & LSUBusAck) |
|
||||
(BusCurrState == STATE_BUS_WRITE & WordCountFlag & LSUBusAck);
|
||||
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_DONE |
|
||||
BusCurrState == STATE_BUS_UNCACHED_WRITE |
|
||||
|
@ -31,10 +31,10 @@ module lrsc
|
||||
input logic clk, reset,
|
||||
input logic FlushW, CPUBusy,
|
||||
input logic MemReadM,
|
||||
input logic [1:0] PreLsuRWM,
|
||||
output logic [1:0] LsuRWM,
|
||||
input logic [1:0] LsuAtomicM,
|
||||
input logic [`PA_BITS-1:0] LsuPAdrM, // from mmu to dcache
|
||||
input logic [1:0] PreLSURWM,
|
||||
output logic [1:0] LSURWM,
|
||||
input logic [1:0] LSUAtomicM,
|
||||
input logic [`PA_BITS-1:0] LSUPAdrM, // from mmu to dcache
|
||||
output logic SquashSCW
|
||||
);
|
||||
// Handle atomic load reserved / store conditional
|
||||
@ -43,17 +43,17 @@ module lrsc
|
||||
logic lrM, scM, WriteAdrMatchM;
|
||||
logic SquashSCM;
|
||||
|
||||
assign lrM = MemReadM & LsuAtomicM[0];
|
||||
assign scM = PreLsuRWM[0] & LsuAtomicM[0];
|
||||
assign WriteAdrMatchM = PreLsuRWM[0] & (LsuPAdrM[`PA_BITS-1:2] == ReservationPAdrW) & ReservationValidW;
|
||||
assign lrM = MemReadM & LSUAtomicM[0];
|
||||
assign scM = PreLSURWM[0] & LSUAtomicM[0];
|
||||
assign WriteAdrMatchM = PreLSURWM[0] & (LSUPAdrM[`PA_BITS-1:2] == ReservationPAdrW) & ReservationValidW;
|
||||
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)
|
||||
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 ReservationValidM = ReservationValidW; // otherwise don't change valid
|
||||
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) squashreg(clk, reset, FlushW, ~CPUBusy, SquashSCM, SquashSCW);
|
||||
endmodule
|
||||
|
@ -63,13 +63,13 @@ module lsu
|
||||
output logic StoreMisalignedFaultM, StoreAccessFaultM,
|
||||
|
||||
// connect to ahb
|
||||
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] LsuBusAdr,
|
||||
(* mark_debug = "true" *) output logic LsuBusRead,
|
||||
(* mark_debug = "true" *) output logic LsuBusWrite,
|
||||
(* mark_debug = "true" *) input logic LsuBusAck,
|
||||
(* mark_debug = "true" *) input logic [`XLEN-1:0] LsuBusHRDATA,
|
||||
(* mark_debug = "true" *) output logic [`XLEN-1:0] LsuBusHWDATA,
|
||||
(* mark_debug = "true" *) output logic [2:0] LsuBusSize,
|
||||
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] LSUBusAdr,
|
||||
(* mark_debug = "true" *) output logic LSUBusRead,
|
||||
(* mark_debug = "true" *) output logic LSUBusWrite,
|
||||
(* mark_debug = "true" *) input logic LSUBusAck,
|
||||
(* mark_debug = "true" *) input logic [`XLEN-1:0] LSUBusHRDATA,
|
||||
(* mark_debug = "true" *) output logic [`XLEN-1:0] LSUBusHWDATA,
|
||||
(* mark_debug = "true" *) output logic [2:0] LSUBusSize,
|
||||
|
||||
// mmu management
|
||||
|
||||
@ -90,17 +90,17 @@ module lsu
|
||||
|
||||
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 DTLBMissM;
|
||||
logic DTLBWriteM;
|
||||
|
||||
logic [1:0] LsuRWM;
|
||||
logic [1:0] PreLsuRWM;
|
||||
logic [2:0] LsuFunct3M;
|
||||
logic [1:0] LsuAtomicM;
|
||||
(* mark_debug = "true" *) logic [`PA_BITS-1:0] PreLsuPAdrM, LocalLsuBusAdr;
|
||||
logic [11:0] PreLsuAdrE, LsuAdrE;
|
||||
logic [1:0] LSURWM;
|
||||
logic [1:0] PreLSURWM;
|
||||
logic [2:0] LSUFunct3M;
|
||||
logic [1:0] LSUAtomicM;
|
||||
(* mark_debug = "true" *) logic [`PA_BITS-1:0] PreLSUPAdrM, LocalLSUBusAdr;
|
||||
logic [11:0] PreLSUAdrE, LSUAdrE;
|
||||
logic CPUBusy;
|
||||
logic MemReadM;
|
||||
logic DCacheStall;
|
||||
@ -144,11 +144,11 @@ module lsu
|
||||
// arbiter between IEU and hptw
|
||||
|
||||
// multiplex the outputs to LSU
|
||||
mux2 #(2) rwmux(MemRWM, {HPTWRead, 1'b0}, SelHPTW, PreLsuRWM);
|
||||
mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LsuFunct3M);
|
||||
mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LsuAtomicM);
|
||||
mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, PreLsuAdrE);
|
||||
mux2 #(`PA_BITS) lsupadrmux(IEUAdrExtM[`PA_BITS-1:0], HPTWAdr, SelHPTW, PreLsuPAdrM);
|
||||
mux2 #(2) rwmux(MemRWM, {HPTWRead, 1'b0}, SelHPTW, PreLSURWM);
|
||||
mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LSUFunct3M);
|
||||
mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LSUAtomicM);
|
||||
mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, PreLSUAdrE);
|
||||
mux2 #(`PA_BITS) lsupadrmux(IEUAdrExtM[`PA_BITS-1:0], HPTWAdr, SelHPTW, PreLSUPAdrM);
|
||||
|
||||
// always block interrupts when using the hardware page table walker.
|
||||
assign CPUBusy = StallW & ~SelHPTW;
|
||||
@ -158,17 +158,17 @@ module lsu
|
||||
//flop #(`PA_BITS) HPTWAdrMReg(clk, HPTWAdr, HPTWAdrM); // delay HPTWAdrM by a cycle
|
||||
|
||||
// Specify which type of page fault is occurring
|
||||
assign DTLBLoadPageFaultM = DTLBPageFaultM & PreLsuRWM[1];
|
||||
assign DTLBStorePageFaultM = DTLBPageFaultM & PreLsuRWM[0];
|
||||
assign DTLBLoadPageFaultM = DTLBPageFaultM & PreLSURWM[1];
|
||||
assign DTLBStorePageFaultM = DTLBPageFaultM & PreLSURWM[0];
|
||||
|
||||
// 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)
|
||||
else begin
|
||||
assign InterlockStall = 1'b0;
|
||||
|
||||
assign LsuAdrE = PreLsuAdrE;
|
||||
assign LSUAdrE = PreLSUAdrE;
|
||||
assign SelHPTW = 1'b0;
|
||||
assign IgnoreRequest = 1'b0;
|
||||
|
||||
@ -177,11 +177,11 @@ module lsu
|
||||
assign DTLBWriteM = 1'b0;
|
||||
assign ITLBWriteF = 1'b0;
|
||||
|
||||
assign PreLsuRWM = MemRWM;
|
||||
assign LsuFunct3M = Funct3M;
|
||||
assign LsuAtomicM = AtomicM;
|
||||
assign PreLsuAdrE = IEUAdrE[11:0];
|
||||
assign PreLsuPAdrM = IEUAdrExtM;
|
||||
assign PreLSURWM = MemRWM;
|
||||
assign LSUFunct3M = Funct3M;
|
||||
assign LSUAtomicM = AtomicM;
|
||||
assign PreLSUAdrE = IEUAdrE[11:0];
|
||||
assign PreLSUPAdrM = IEUAdrExtM;
|
||||
assign CPUBusy = StallW;
|
||||
|
||||
assign DTLBLoadPageFaultM = 1'b0;
|
||||
@ -204,21 +204,21 @@ module lsu
|
||||
mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0))
|
||||
dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
|
||||
.PrivilegeModeW, .DisableTranslation(SelHPTW),
|
||||
.PAdr(PreLsuPAdrM),
|
||||
.PAdr(PreLSUPAdrM),
|
||||
.VAdr(IEUAdrM),
|
||||
.Size(LsuFunct3M[1:0]),
|
||||
.Size(LSUFunct3M[1:0]),
|
||||
.PTE,
|
||||
.PageTypeWriteVal(PageType),
|
||||
.TLBWrite(DTLBWriteM),
|
||||
.TLBFlush(DTLBFlushM),
|
||||
.PhysicalAddress(LsuPAdrM),
|
||||
.PhysicalAddress(LSUPAdrM),
|
||||
.TLBMiss(DTLBMissM),
|
||||
.Cacheable(CacheableM),
|
||||
.Idempotent(), .AtomicAllowed(),
|
||||
.TLBPageFault(DTLBPageFaultM),
|
||||
.InstrAccessFaultF(), .LoadAccessFaultM, .StoreAccessFaultM,
|
||||
.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
|
||||
); // *** 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];
|
||||
|
||||
end else begin
|
||||
assign LsuPAdrM = PreLsuPAdrM;
|
||||
assign LSUPAdrM = PreLSUPAdrM;
|
||||
assign DTLBMissM = 0;
|
||||
assign CacheableM = 1;
|
||||
assign DTLBPageFaultM = 0;
|
||||
@ -249,14 +249,14 @@ module lsu
|
||||
assign LSUStall = DCacheStall | InterlockStall | BusStall;
|
||||
|
||||
|
||||
// use PreLsu as prefix for lrsc
|
||||
// use PreLSU as prefix for lrsc
|
||||
if (`A_SUPPORTED) begin:lrsc
|
||||
assign MemReadM = PreLsuRWM[1] & ~(IgnoreRequest) & ~DTLBMissM;
|
||||
lrsc lrsc(.clk, .reset, .FlushW, .CPUBusy, .MemReadM, .PreLsuRWM, .LsuAtomicM, .LsuPAdrM,
|
||||
.SquashSCW, .LsuRWM);
|
||||
assign MemReadM = PreLSURWM[1] & ~(IgnoreRequest) & ~DTLBMissM;
|
||||
lrsc lrsc(.clk, .reset, .FlushW, .CPUBusy, .MemReadM, .PreLSURWM, .LSUAtomicM, .LSUPAdrM,
|
||||
.SquashSCW, .LSURWM);
|
||||
end else begin:lrsc
|
||||
assign SquashSCW = 0;
|
||||
assign LsuRWM = PreLsuRWM;
|
||||
assign LSURWM = PreLSURWM;
|
||||
end
|
||||
|
||||
|
||||
@ -276,7 +276,7 @@ module lsu
|
||||
// temp
|
||||
|
||||
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 [LINELEN-1:0] DCacheMemWriteData;
|
||||
|
||||
@ -300,8 +300,8 @@ module lsu
|
||||
cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN),
|
||||
.NUMWAYS(`DCACHE_NUMWAYS), .DCACHE(1))
|
||||
dcache(.clk, .reset, .CPUBusy,
|
||||
.RW(CacheableM ? LsuRWM : 2'b00), .FlushCache(FlushDCacheM), .Atomic(CacheableM ? LsuAtomicM : 2'b00),
|
||||
.NextAdr(LsuAdrE), .PAdr(LsuPAdrM), .NoTranAdr(PreLsuPAdrM[11:0]),
|
||||
.RW(CacheableM ? LSURWM : 2'b00), .FlushCache(FlushDCacheM), .Atomic(CacheableM ? LSUAtomicM : 2'b00),
|
||||
.NextAdr(LSUAdrE), .PAdr(LSUPAdrM), .NoTranAdr(PreLSUPAdrM[11:0]),
|
||||
.FinalWriteData(FinalWriteDataM), .ReadDataWord(ReadDataWordM), .CacheStall(DCacheStall),
|
||||
.CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess),
|
||||
.IgnoreRequest, .CacheCommitted(DCacheCommittedM),
|
||||
@ -330,23 +330,23 @@ module lsu
|
||||
// sub word selection for read and writes and optional amo alu.
|
||||
// finally swr
|
||||
subwordread subwordread(.ReadDataWordMuxM,
|
||||
.LsuPAdrM(LsuPAdrM[2:0]),
|
||||
.Funct3M(LsuFunct3M),
|
||||
.LSUPAdrM(LSUPAdrM[2:0]),
|
||||
.Funct3M(LSUFunct3M),
|
||||
.ReadDataM);
|
||||
|
||||
if (`A_SUPPORTED) begin : amo
|
||||
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));
|
||||
mux2 #(`XLEN) wdmux(WriteDataM, AMOResult, LsuAtomicM[1], FinalAMOWriteDataM);
|
||||
mux2 #(`XLEN) wdmux(WriteDataM, AMOResult, LSUAtomicM[1], FinalAMOWriteDataM);
|
||||
end else
|
||||
assign FinalAMOWriteDataM = WriteDataM;
|
||||
|
||||
// this might only get instantiated if there is a dcache or dtim.
|
||||
// There is a copy in the ebu.
|
||||
subwordwrite subwordwrite(.HRDATA(ReadDataWordM),
|
||||
.HADDRD(LsuPAdrM[2:0]),
|
||||
.HSIZED({LsuFunct3M[2], 1'b0, LsuFunct3M[1:0]}),
|
||||
.HADDRD(LSUPAdrM[2:0]),
|
||||
.HSIZED({LSUFunct3M[2], 1'b0, LSUFunct3M[1:0]}),
|
||||
.HWDATAIN(FinalAMOWriteDataM),
|
||||
.HWDATA(FinalWriteDataM));
|
||||
|
||||
@ -359,22 +359,22 @@ module lsu
|
||||
genvar index;
|
||||
for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer
|
||||
flopen #(`XLEN) fb(.clk,
|
||||
.en(LsuBusAck & LsuBusRead & (index == WordCount)),
|
||||
.d(LsuBusHRDATA),
|
||||
.en(LSUBusAck & LSUBusRead & (index == WordCount)),
|
||||
.d(LSUBusHRDATA),
|
||||
.q(DCacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN]));
|
||||
end
|
||||
|
||||
assign LocalLsuBusAdr = SelUncachedAdr ? LsuPAdrM : DCacheBusAdr ;
|
||||
assign LsuBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLsuBusAdr;
|
||||
assign PreLsuBusHWDATA = ReadDataLineSetsM[WordCount];
|
||||
assign LsuBusHWDATA = SelUncachedAdr ? WriteDataM : PreLsuBusHWDATA; // *** why is this not FinalWriteDataM? which does not work.
|
||||
assign LocalLSUBusAdr = SelUncachedAdr ? LSUPAdrM : DCacheBusAdr ;
|
||||
assign LSUBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLSUBusAdr;
|
||||
assign PreLSUBusHWDATA = ReadDataLineSetsM[WordCount];
|
||||
assign LSUBusHWDATA = SelUncachedAdr ? WriteDataM : PreLSUBusHWDATA; // *** why is this not FinalWriteDataM? which does not work.
|
||||
|
||||
if (`XLEN == 32) assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b010;
|
||||
else assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b011;
|
||||
if (`XLEN == 32) assign LSUBusSize = SelUncachedAdr ? LSUFunct3M : 3'b010;
|
||||
else assign LSUBusSize = SelUncachedAdr ? LSUFunct3M : 3'b011;
|
||||
|
||||
busfsm #(WordCountThreshold, LOGWPL, `MEM_DCACHE)
|
||||
busfsm(.clk, .reset, .IgnoreRequest, .LsuRWM, .DCacheFetchLine, .DCacheWriteLine,
|
||||
.LsuBusAck, .CPUBusy, .CacheableM, .BusStall, .LsuBusWrite, .LsuBusRead,
|
||||
busfsm(.clk, .reset, .IgnoreRequest, .LSURWM, .DCacheFetchLine, .DCacheWriteLine,
|
||||
.LSUBusAck, .CPUBusy, .CacheableM, .BusStall, .LSUBusWrite, .LSUBusRead,
|
||||
.DCacheBusAck, .BusCommittedM, .SelUncachedAdr, .WordCount);
|
||||
|
||||
endmodule
|
||||
|
@ -28,7 +28,7 @@
|
||||
module subwordread
|
||||
(
|
||||
input logic [`XLEN-1:0] ReadDataWordMuxM,
|
||||
input logic [2:0] LsuPAdrM,
|
||||
input logic [2:0] LSUPAdrM,
|
||||
input logic [2:0] Funct3M,
|
||||
output logic [`XLEN-1:0] ReadDataM
|
||||
);
|
||||
@ -41,7 +41,7 @@ module subwordread
|
||||
if (`XLEN == 64) begin:swrmux
|
||||
// ByteMe mux
|
||||
always_comb
|
||||
case(LsuPAdrM[2:0])
|
||||
case(LSUPAdrM[2:0])
|
||||
3'b000: ByteM = ReadDataWordMuxM[7:0];
|
||||
3'b001: ByteM = ReadDataWordMuxM[15:8];
|
||||
3'b010: ByteM = ReadDataWordMuxM[23:16];
|
||||
@ -54,7 +54,7 @@ module subwordread
|
||||
|
||||
// halfword mux
|
||||
always_comb
|
||||
case(LsuPAdrM[2:1])
|
||||
case(LSUPAdrM[2:1])
|
||||
2'b00: HalfwordM = ReadDataWordMuxM[15:0];
|
||||
2'b01: HalfwordM = ReadDataWordMuxM[31:16];
|
||||
2'b10: HalfwordM = ReadDataWordMuxM[47:32];
|
||||
@ -64,7 +64,7 @@ module subwordread
|
||||
logic [31:0] WordM;
|
||||
|
||||
always_comb
|
||||
case(LsuPAdrM[2])
|
||||
case(LSUPAdrM[2])
|
||||
1'b0: WordM = ReadDataWordMuxM[31:0];
|
||||
1'b1: WordM = ReadDataWordMuxM[63:32];
|
||||
endcase
|
||||
@ -84,7 +84,7 @@ module subwordread
|
||||
end else begin:swrmux // 32-bit
|
||||
// byte mux
|
||||
always_comb
|
||||
case(LsuPAdrM[1:0])
|
||||
case(LSUPAdrM[1:0])
|
||||
2'b00: ByteM = ReadDataWordMuxM[7:0];
|
||||
2'b01: ByteM = ReadDataWordMuxM[15:8];
|
||||
2'b10: ByteM = ReadDataWordMuxM[23:16];
|
||||
@ -93,7 +93,7 @@ module subwordread
|
||||
|
||||
// halfword mux
|
||||
always_comb
|
||||
case(LsuPAdrM[1])
|
||||
case(LSUPAdrM[1])
|
||||
1'b0: HalfwordM = ReadDataWordMuxM[15:0];
|
||||
1'b1: HalfwordM = ReadDataWordMuxM[31:16];
|
||||
endcase
|
||||
|
@ -31,16 +31,16 @@ module muldiv (
|
||||
// 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 [2:0] Funct3E, Funct3M,
|
||||
input logic MulDivE, W64E,
|
||||
input logic MDUE, W64E,
|
||||
// Writeback stage
|
||||
output logic [`XLEN-1:0] MulDivResultW,
|
||||
output logic [`XLEN-1:0] MDUResultW,
|
||||
// Divide Done
|
||||
output logic DivBusyE,
|
||||
// hazards
|
||||
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] QuotM, RemM;
|
||||
logic [`XLEN*2-1:0] ProdM;
|
||||
@ -54,7 +54,7 @@ module muldiv (
|
||||
|
||||
// Divide
|
||||
// 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];
|
||||
intdivrestoring div(.clk, .reset, .StallM, .DivSignedE, .W64E, .DivE,
|
||||
.ForwardedSrcAE, .ForwardedSrcBE, .DivBusyE, .QuotM, .RemM);
|
||||
@ -75,13 +75,13 @@ module muldiv (
|
||||
// Handle sign extension for W-type instructions
|
||||
flopenrc #(1) W64MReg(clk, reset, FlushM, ~StallM, W64E, W64M);
|
||||
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
|
||||
assign MulDivResultM = PrelimResultM;
|
||||
assign MDUResultM = PrelimResultM;
|
||||
end
|
||||
|
||||
// Writeback stage pipeline register
|
||||
flopenrc #(`XLEN) MulDivResultWReg(clk, reset, FlushW, ~StallW, MulDivResultM, MulDivResultW);
|
||||
flopenrc #(`XLEN) MDUResultWReg(clk, reset, FlushW, ~StallW, MDUResultM, MDUResultW);
|
||||
endmodule // muldiv
|
||||
|
||||
|
||||
|
@ -56,7 +56,7 @@ module wallypipelinedhart (
|
||||
(* mark_debug = "true" *) logic TrapM;
|
||||
|
||||
// new signals that must connect through DP
|
||||
logic MulDivE, W64E;
|
||||
logic MDUE, W64E;
|
||||
logic CSRReadM, CSRWriteM, PrivilegedM;
|
||||
logic [1:0] AtomicE;
|
||||
logic [1:0] AtomicM;
|
||||
@ -68,7 +68,7 @@ module wallypipelinedhart (
|
||||
(* mark_debug = "true" *) logic [31:0] InstrM;
|
||||
logic [`XLEN-1:0] PCF, PCD, PCE, PCLinkE;
|
||||
(* 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;
|
||||
(* mark_debug = "true" *) logic [1:0] MemRWM;
|
||||
(* mark_debug = "true" *) logic InstrValidM;
|
||||
@ -82,7 +82,7 @@ module wallypipelinedhart (
|
||||
logic PCSrcE;
|
||||
logic CSRWritePendingDEM;
|
||||
logic DivBusyE;
|
||||
logic LoadStallD, StoreStallD, MulDivStallD, CSRRdStallD;
|
||||
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD;
|
||||
logic SquashSCW;
|
||||
// floating point unit signals
|
||||
logic [2:0] FRM_REGW;
|
||||
@ -113,7 +113,7 @@ module wallypipelinedhart (
|
||||
var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0];
|
||||
|
||||
// IMem stalls
|
||||
logic IfuStallF;
|
||||
logic IFUStallF;
|
||||
logic LSUStall;
|
||||
|
||||
|
||||
@ -128,18 +128,18 @@ module wallypipelinedhart (
|
||||
logic CommittedM;
|
||||
|
||||
// AHB ifu interface
|
||||
logic [`PA_BITS-1:0] IfuBusAdr;
|
||||
logic [`XLEN-1:0] IfuBusHRDATA;
|
||||
logic IfuBusRead;
|
||||
logic IfuBusAck;
|
||||
logic [`PA_BITS-1:0] IFUBusAdr;
|
||||
logic [`XLEN-1:0] IFUBusHRDATA;
|
||||
logic IFUBusRead;
|
||||
logic IFUBusAck;
|
||||
|
||||
// AHB LSU interface
|
||||
logic [`PA_BITS-1:0] LsuBusAdr;
|
||||
logic LsuBusRead;
|
||||
logic LsuBusWrite;
|
||||
logic LsuBusAck;
|
||||
logic [`XLEN-1:0] LsuBusHRDATA;
|
||||
logic [`XLEN-1:0] LsuBusHWDATA;
|
||||
logic [`PA_BITS-1:0] LSUBusAdr;
|
||||
logic LSUBusRead;
|
||||
logic LSUBusWrite;
|
||||
logic LSUBusAck;
|
||||
logic [`XLEN-1:0] LSUBusHRDATA;
|
||||
logic [`XLEN-1:0] LSUBusHWDATA;
|
||||
|
||||
logic BPPredWrongE;
|
||||
logic BPPredDirWrongM;
|
||||
@ -148,7 +148,7 @@ module wallypipelinedhart (
|
||||
logic BPPredClassNonCFIWrongM;
|
||||
logic [4:0] InstrClassM;
|
||||
logic InstrAccessFaultF;
|
||||
logic [2:0] LsuBusSize;
|
||||
logic [2:0] LSUBusSize;
|
||||
|
||||
logic ExceptionM;
|
||||
logic PendingInterruptM;
|
||||
@ -164,8 +164,8 @@ module wallypipelinedhart (
|
||||
|
||||
.ExceptionM, .PendingInterruptM,
|
||||
// Fetch
|
||||
.IfuBusHRDATA, .IfuBusAck, .PCF, .IfuBusAdr,
|
||||
.IfuBusRead, .IfuStallF,
|
||||
.IFUBusHRDATA, .IFUBusAck, .PCF, .IFUBusAdr,
|
||||
.IFUBusRead, .IFUStallF,
|
||||
|
||||
// Execute
|
||||
.PCLinkE, .PCSrcE, .IEUAdrE, .PCE,
|
||||
@ -206,7 +206,7 @@ module wallypipelinedhart (
|
||||
|
||||
// Execute Stage interface
|
||||
.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
|
||||
|
||||
// Memory stage interface
|
||||
@ -220,14 +220,14 @@ module wallypipelinedhart (
|
||||
.RdM, .FIntResM, .InvalidateICacheM, .FlushDCacheM,
|
||||
|
||||
// Writeback stage
|
||||
.CSRReadValW, .ReadDataM, .MulDivResultW,
|
||||
.CSRReadValW, .ReadDataM, .MDUResultW,
|
||||
.RdW, .ReadDataW,
|
||||
.InstrValidM,
|
||||
|
||||
// hazards
|
||||
.StallD, .StallE, .StallM, .StallW,
|
||||
.FlushD, .FlushE, .FlushM, .FlushW,
|
||||
.FPUStallD, .LoadStallD, .MulDivStallD, .CSRRdStallD,
|
||||
.FPUStallD, .LoadStallD, .MDUStallD, .CSRRdStallD,
|
||||
.PCSrcE,
|
||||
.CSRReadM, .CSRWriteM, .PrivilegedM,
|
||||
.CSRWritePendingDEM, .StoreStallD
|
||||
@ -246,8 +246,8 @@ module wallypipelinedhart (
|
||||
.IEUAdrE, .IEUAdrM, .WriteDataM,
|
||||
.ReadDataM, .FlushDCacheM,
|
||||
// connected to ahb (all stay the same)
|
||||
.LsuBusAdr, .LsuBusRead, .LsuBusWrite, .LsuBusAck,
|
||||
.LsuBusHRDATA, .LsuBusHWDATA, .LsuBusSize,
|
||||
.LSUBusAdr, .LSUBusRead, .LSUBusWrite, .LSUBusAck,
|
||||
.LSUBusHRDATA, .LSUBusHWDATA, .LSUBusSize,
|
||||
|
||||
// connect to csr or privilege and stay the same.
|
||||
.PrivilegeModeW, // connects to csr
|
||||
@ -277,13 +277,13 @@ module wallypipelinedhart (
|
||||
ahblite ebu(// IFU connections
|
||||
.clk, .reset,
|
||||
.UnsignedLoadM(1'b0), .AtomicMaskedM(2'b00),
|
||||
.IfuBusAdr,
|
||||
.IfuBusRead, .IfuBusHRDATA, .IfuBusAck,
|
||||
.IFUBusAdr,
|
||||
.IFUBusRead, .IFUBusHRDATA, .IFUBusAck,
|
||||
// Signals from Data Cache
|
||||
.LsuBusAdr, .LsuBusRead, .LsuBusWrite, .LsuBusHWDATA,
|
||||
.LsuBusHRDATA,
|
||||
.LsuBusSize,
|
||||
.LsuBusAck,
|
||||
.LSUBusAdr, .LSUBusRead, .LSUBusWrite, .LSUBusHWDATA,
|
||||
.LSUBusHRDATA,
|
||||
.LSUBusSize,
|
||||
.LSUBusAck,
|
||||
|
||||
.HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn,
|
||||
.HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST,
|
||||
@ -293,8 +293,8 @@ module wallypipelinedhart (
|
||||
|
||||
hazard hzu(
|
||||
.BPPredWrongE, .CSRWritePendingDEM, .RetM, .TrapM,
|
||||
.LoadStallD, .StoreStallD, .MulDivStallD, .CSRRdStallD,
|
||||
.LSUStall, .IfuStallF,
|
||||
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD,
|
||||
.LSUStall, .IFUStallF,
|
||||
.FPUStallD, .FStallD,
|
||||
.DivBusyE, .FDivBusyE,
|
||||
.EcallFaultM, .BreakpointFaultM,
|
||||
@ -347,12 +347,12 @@ module wallypipelinedhart (
|
||||
muldiv mdu(
|
||||
.clk, .reset,
|
||||
.ForwardedSrcAE, .ForwardedSrcBE,
|
||||
.Funct3E, .Funct3M, .MulDivE, .W64E,
|
||||
.MulDivResultW, .DivBusyE,
|
||||
.Funct3E, .Funct3M, .MDUE, .W64E,
|
||||
.MDUResultW, .DivBusyE,
|
||||
.StallM, .StallW, .FlushM, .FlushW
|
||||
);
|
||||
end else begin // no M instructions supported
|
||||
assign MulDivResultW = 0;
|
||||
assign MDUResultW = 0;
|
||||
assign DivBusyE = 0;
|
||||
end
|
||||
|
||||
|
@ -438,7 +438,7 @@ module testbench;
|
||||
end \
|
||||
if(`"STAGE`"=="M") begin \
|
||||
// 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); \
|
||||
force dut.hart.ieu.dp.ReadDataM = ExpectedMemReadDataM; \
|
||||
else \
|
||||
|
Loading…
Reference in New Issue
Block a user