forked from Github_Repos/cvw
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:
parent
20546857e6
commit
68aa1434b4
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user