Modified the LSU and IFU to allow concurrent DTIM/DCACHE+BUS and IROM/ICACHE+BUS.

Don't use this commit as the rv32i tests are not passing.
This commit is contained in:
Ross Thompson 2022-10-05 14:51:02 -05:00
parent 20546857e6
commit 68aa1434b4
4 changed files with 42 additions and 27 deletions

View File

@ -91,7 +91,7 @@ module ifu (
logic [`XLEN-1:0] PCPlus2or4F, PCLinkD;
logic [`XLEN-3:0] PCPlusUpperF;
logic CompressedF;
logic [31:0] InstrRawD, InstrRawF;
logic [31:0] InstrRawD, InstrRawF, InstrRaw2F, IROMInstrRawF, ICacheInstrRawF;
logic [31:0] FinalInstrRawF;
logic [1:0] IFURWF;
@ -118,6 +118,8 @@ module ifu (
// branch predictor signal
logic [`XLEN-1:0] PCNext1F, PCNext2F, PCNext0F;
logic BusCommittedF, CacheCommittedF;
logic SelIROM;
assign PCFExt = {2'b00, PCFSpill};
@ -128,7 +130,7 @@ module ifu (
if(`C_SUPPORTED) begin : SpillSupport
spillsupport #(`ICACHE) spillsupport(.clk, .reset, .StallF, .PCF, .PCPlusUpperF, .PCNextF, .InstrRawF,
spillsupport #(`ICACHE) spillsupport(.clk, .reset, .StallF, .PCF, .PCPlusUpperF, .PCNextF, .InstrRawF(InstrRaw2F),
.InstrDAPageFaultF, .IFUCacheBusStallF, .ITLBMissF, .PCNextFSpill, .PCFSpill,
.SelNextSpillF, .PostSpillInstrRawF, .CompressedF);
end else begin : NoSpillSupport
@ -166,7 +168,7 @@ module ifu (
.TLBFlush,
.PhysicalAddress(PCPF),
.TLBMiss(ITLBMissF),
.Cacheable(CacheableF), .Idempotent(), .AtomicAllowed(),
.Cacheable(CacheableF), .Idempotent(), .AtomicAllowed(), .SelTIM(SelIROM),
.InstrAccessFaultF, .LoadAccessFaultM(), .StoreAmoAccessFaultM(),
.InstrPageFaultF, .LoadPageFaultM(), .StoreAmoPageFaultM(),
.LoadMisalignedFaultM(), .StoreAmoMisalignedFaultM(),
@ -196,7 +198,7 @@ module ifu (
// The IROM uses untranslated addresses, so it is not compatible with virtual memory.
if (`IROM_SUPPORTED) begin : irom
assign IFURWF = 2'b10;
irom irom(.clk, .reset, .ce(~CPUBusy), .Adr(PCNextFSpill[`XLEN-1:0]), .ReadData(FinalInstrRawF));
irom irom(.clk, .reset, .ce(~CPUBusy), .Adr(PCNextFSpill[`XLEN-1:0]), .ReadData(IROMInstrRawF));
end else begin
assign IFURWF = 2'b10;
@ -222,7 +224,7 @@ module ifu (
.FetchBuffer, .CacheBusAck(ICacheBusAck),
.CacheBusAdr(ICacheBusAdr), .CacheStall(ICacheStallF),
.CacheBusRW,
.ReadDataWord(FinalInstrRawF),
.ReadDataWord(ICacheInstrRawF),
.Cacheable(CacheableF),
.SelReplay('0),
.CacheMiss(ICacheMiss), .CacheAccess(ICacheAccess),
@ -244,11 +246,14 @@ module ifu (
.BusRW, .CPUBusy,
.BusStall, .BusCommitted(BusCommittedF));
mux2 #(32) UnCachedDataMux(.d0(FinalInstrRawF), .d1(FetchBuffer[32-1:0]),
.s(SelUncachedAdr), .y(InstrRawF[31:0]));
mux2 #(32) UnCachedDataMux(.d0(ICacheInstrRawF), .d1(FetchBuffer[32-1:0]),
.s(SelUncachedAdr), .y(InstrRawF));
mux2 #(32) UnCachedDataMux2(.d0(InstrRawF), .d1(IROMInstrRawF),
.s(SelIROM), .y(InstrRaw2F[31:0]));
end else begin : passthrough
assign IFUHADDR = PCPF;
logic CaptureEn;
logic [31:0] FetchBuffer;
logic [1:0] BusRW;
assign BusRW = IFURWF & ~{ITLBMissF, ITLBMissF} & ~{TrapM, TrapM};
assign IFUHSIZE = 3'b010;
@ -256,8 +261,10 @@ module ifu (
ahbinterface #(0) ahbinterface(.HCLK(clk), .HRESETn(~reset), .HREADY(IFUHREADY),
.HRDATA(HRDATA), .HTRANS(IFUHTRANS), .HWRITE(IFUHWRITE), .HWDATA(),
.HWSTRB(), .BusRW, .ByteMask(), .WriteData('0),
.CPUBusy, .BusStall, .BusCommitted(BusCommittedF), .FetchBuffer(InstrRawF[31:0]));
.CPUBusy, .BusStall, .BusCommitted(BusCommittedF), .FetchBuffer(FetchBuffer));
if(`IROM_SUPPORTED) mux2 #(32) UnCachedDataMux2(FetchBuffer, IROMInstrRawF, SelIROM, InstrRaw2F);
else assign InstrRaw2F = FetchBuffer;
assign IFUHBURST = 3'b0;
assign {ICacheFetchLine, ICacheStallF, FinalInstrRawF} = '0;
assign {ICacheMiss, ICacheAccess} = '0;
@ -265,7 +272,7 @@ module ifu (
end else begin : nobus // block: bus
assign BusStall = '0;
assign {ICacheStallF, ICacheMiss, ICacheAccess} = '0;
assign InstrRawF = FinalInstrRawF;
assign InstrRaw2F = IROMInstrRawF;
end
assign IFUCacheBusStallF = ICacheStallF | BusStall;

View File

@ -117,6 +117,7 @@ module lsu (
logic [`LLEN-1:0] ReadDataM;
logic [(`LLEN-1)/8:0] ByteMaskM;
logic SelReplay;
logic SelDTIM;
flopenrc #(`XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM);
assign IEUAdrExtM = {2'b00, IEUAdrM};
@ -168,7 +169,7 @@ module lsu (
.TLBFlush(sfencevmaM),
.PhysicalAddress(PAdrM),
.TLBMiss(DTLBMissM),
.Cacheable(CacheableM), .Idempotent(), .AtomicAllowed(),
.Cacheable(CacheableM), .Idempotent(), .AtomicAllowed(), .SelTIM(SelDTIM),
.InstrAccessFaultF(), .LoadAccessFaultM, .StoreAmoAccessFaultM,
.InstrPageFaultF(),.LoadPageFaultM, .StoreAmoPageFaultM,
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, // *** these faults need to be supressed during hptw.
@ -200,19 +201,21 @@ module lsu (
/////////////////////////////////////////////////////////////////////////////////////////////
logic [`LLEN-1:0] LSUWriteDataM, LittleEndianWriteDataM;
logic [`LLEN-1:0] ReadDataWordM, LittleEndianReadDataWordM;
logic [`LLEN-1:0] ReadDataWordMuxM;
logic [`LLEN-1:0] ReadDataWordMuxM, DTIMReadDataWordM, ReadDataWordMux2M, DCacheReadDataWordM;
logic IgnoreRequest;
assign IgnoreRequest = IgnoreRequestTLB | TrapM;
if (`DTIM_SUPPORTED) begin : dtim
logic [`PA_BITS-1:0] DTIMAdr;
logic [1:0] DTIMMemRWM;
// The DTIM uses untranslated addresses, so it is not compatible with virtual memory.
assign DTIMAdr = MemRWM[0] ? IEUAdrExtM : IEUAdrExtE; // zero extend or contract to PA_BITS
dtim dtim(.clk, .reset, .ce(~CPUBusy), .MemRWM,
assign DTIMMemRWM = LSURWM & ~{IgnoreRequest, IgnoreRequest} & {SelDTIM, SelDTIM};
dtim dtim(.clk, .reset, .ce(~CPUBusy), .MemRWM(DTIMMemRWM),
.Adr(DTIMAdr),
.TrapM, .WriteDataM(LSUWriteDataM),
.ReadDataWordM(ReadDataWordM[`XLEN-1:0]), .ByteMaskM(ByteMaskM[`XLEN/8-1:0]));
.ReadDataWordM(DTIMReadDataWordM[`XLEN-1:0]), .ByteMaskM(ByteMaskM[`XLEN/8-1:0]));
end else begin
end
if (`BUS) begin : bus
@ -231,7 +234,7 @@ module lsu (
logic [`XLEN/8-1:0] ByteMaskMDelay;
logic [1:0] CacheBusRW, BusRW;
assign BusRW = LSURWM & ~{IgnoreRequest, IgnoreRequest} & ~{CacheableM, CacheableM};
assign BusRW = LSURWM & ~{IgnoreRequest, IgnoreRequest} & ~{CacheableM, CacheableM} & ~{SelDTIM, SelDTIM};
cache #(.LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN),
.NUMWAYS(`DCACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(`LLEN), .MUXINTERVAL(`XLEN), .DCACHE(1)) dcache(
@ -241,7 +244,7 @@ module lsu (
.FinalWriteData(LSUWriteDataM), .Cacheable(CacheableM), .SelReplay,
.CacheStall(DCacheStallM), .CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess),
.IgnoreRequestTLB, .TrapM, .CacheCommitted(DCacheCommittedM),
.CacheBusAdr(DCacheBusAdr), .ReadDataWord(ReadDataWordM),
.CacheBusAdr(DCacheBusAdr), .ReadDataWord(DCacheReadDataWordM),
.FetchBuffer, .CacheBusRW,
.CacheBusAck(DCacheBusAck), .InvalidateCache(1'b0));
ahbcacheinterface #(WORDSPERLINE, LINELEN, LOGBWPL, `DCACHE) ahbcacheinterface(
@ -254,9 +257,11 @@ module lsu (
.SelUncachedAdr, .BusRW, .CPUBusy,
.BusStall, .BusCommitted(BusCommittedM));
mux2 #(`LLEN) UnCachedDataMux(.d0(ReadDataWordM), .d1({{`LLEN-`XLEN{1'b0}}, FetchBuffer[`XLEN-1:0] }),
mux2 #(`LLEN) UnCachedDataMux(.d0(DCacheReadDataWordM), .d1({{`LLEN-`XLEN{1'b0}}, FetchBuffer[`XLEN-1:0] }),
.s(SelUncachedAdr), .y(ReadDataWordMuxM));
mux2 #(`XLEN) LSUHWDATAMux(.d0(ReadDataWordM[`XLEN-1:0]), .d1(LSUWriteDataM[`XLEN-1:0]),
mux2 #(`LLEN) ReadDataMux2(.d0(ReadDataWordMuxM), .d1({{`LLEN-`XLEN{1'b0}}, DTIMReadDataWordM[`XLEN-1:0]}),
.s(SelUncachedAdr), .y(ReadDataWordMux2M));
mux2 #(`XLEN) LSUHWDATAMux(.d0(DCacheReadDataWordM[`XLEN-1:0]), .d1(LSUWriteDataM[`XLEN-1:0]),
.s(SelUncachedAdr), .y(PreHWDATA));
flopen #(`XLEN) wdreg(clk, LSUHREADY, PreHWDATA, LSUHWDATA); // delay HWDATA by 1 cycle per spec; *** assumes AHBW = XLEN
@ -271,6 +276,7 @@ module lsu (
end else begin : passthrough // just needs a register to hold the value from the bus
logic CaptureEn;
logic [1:0] BusRW;
logic [`XLEN-1:0] FetchBuffer;
assign BusRW = LSURWM & ~{IgnoreRequest, IgnoreRequest};
assign LSUHADDR = PAdrM;
@ -279,15 +285,16 @@ module lsu (
ahbinterface #(1) ahbinterface(.HCLK(clk), .HRESETn(~reset), .HREADY(LSUHREADY),
.HRDATA(HRDATA), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HWDATA(LSUHWDATA),
.HWSTRB(LSUHWSTRB), .BusRW, .ByteMask(ByteMaskM), .WriteData(LSUWriteDataM),
.CPUBusy, .BusStall, .BusCommitted(BusCommittedM), .FetchBuffer(ReadDataWordM));
assign ReadDataWordMuxM = ReadDataWordM; // from byte swapping
.CPUBusy, .BusStall, .BusCommitted(BusCommittedM), .FetchBuffer(FetchBuffer));
if(`DTIM_SUPPORTED) mux2 #(`XLEN) ReadDataMux2(FetchBuffer, DTIMReadDataWordM, SelDTIM, ReadDataWordMux2M);
else assign ReadDataWordMux2M = FetchBuffer[`XLEN-1:0];
assign LSUHBURST = 3'b0;
assign {DCacheStallM, DCacheCommittedM, DCacheMiss, DCacheAccess} = '0;
end
end else begin: nobus // block: bus
assign LSUHWDATA = '0;
assign ReadDataWordMuxM = ReadDataWordM;
assign ReadDataWordMux2M = DTIMReadDataWordM;
assign {BusStall, BusCommittedM} = '0;
assign {DCacheMiss, DCacheAccess} = '0;
assign {DCacheStallM, DCacheCommittedM} = '0;
@ -334,10 +341,10 @@ module lsu (
/////////////////////////////////////////////////////////////////////////////////////////////
if (`BIGENDIAN_SUPPORTED) begin:endian
endianswap #(`LLEN) storeswap(.BigEndianM, .a(LittleEndianWriteDataM), .y(LSUWriteDataM));
endianswap #(`LLEN) loadswap(.BigEndianM, .a(ReadDataWordMuxM), .y(LittleEndianReadDataWordM));
endianswap #(`LLEN) loadswap(.BigEndianM, .a(ReadDataWordMux2M), .y(LittleEndianReadDataWordM));
end else begin
assign LSUWriteDataM = LittleEndianWriteDataM;
assign LittleEndianReadDataWordM = ReadDataWordMuxM;
assign LittleEndianReadDataWordM = ReadDataWordMux2M;
end
endmodule

View File

@ -66,7 +66,7 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
// Physical address outputs
output logic [`PA_BITS-1:0] PhysicalAddress,
output logic TLBMiss,
output logic Cacheable, Idempotent, AtomicAllowed,
output logic Cacheable, Idempotent, AtomicAllowed, SelTIM,
// Faults
output logic InstrAccessFaultF, LoadAccessFaultM, StoreAmoAccessFaultM,
@ -126,7 +126,7 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
pmachecker pmachecker(.PhysicalAddress, .Size,
.AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM,
.Cacheable, .Idempotent, .AtomicAllowed,
.Cacheable, .Idempotent, .AtomicAllowed, .SelTIM,
.PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM);
pmpchecker pmpchecker(.PhysicalAddress, .PrivilegeModeW,

View File

@ -38,7 +38,7 @@ module pmachecker (
input logic [`PA_BITS-1:0] PhysicalAddress,
input logic [1:0] Size,
input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // *** atomicaccessM is unused but might want to stay in for future use.
output logic Cacheable, Idempotent, AtomicAllowed,
output logic Cacheable, Idempotent, AtomicAllowed, SelTIM,
output logic PMAInstrAccessFaultF,
output logic PMALoadAccessFaultM,
output logic PMAStoreAmoAccessFaultM
@ -60,6 +60,7 @@ module pmachecker (
assign Cacheable = SelRegions[8] | SelRegions[7] | SelRegions[6];
assign Idempotent = SelRegions[10] | SelRegions[9] | SelRegions[8] | SelRegions[6];
assign AtomicAllowed = SelRegions[10] | SelRegions[9] | SelRegions[8] | SelRegions[6];
assign SelTIM = SelRegions[10] | SelRegions[9];
// Detect access faults
assign PMAAccessFault = (SelRegions[0]) & AccessRWX;