Capitalized LSU and IFU, changed MulDiv to MDU

This commit is contained in:
David Harris 2022-01-07 04:30:00 +00:00
parent 0e023e29d8
commit 1d8451c2cf
14 changed files with 200 additions and 200 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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 |

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 \