From 68aa1434b4dfb5131bb260733dbc5c2b0cea2161 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 5 Oct 2022 14:51:02 -0500 Subject: [PATCH] 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. --- pipelined/src/ifu/ifu.sv | 25 ++++++++++++++-------- pipelined/src/lsu/lsu.sv | 37 ++++++++++++++++++++------------- pipelined/src/mmu/mmu.sv | 4 ++-- pipelined/src/mmu/pmachecker.sv | 3 ++- 4 files changed, 42 insertions(+), 27 deletions(-) diff --git a/pipelined/src/ifu/ifu.sv b/pipelined/src/ifu/ifu.sv index 8bda30b0..35bd22ff 100644 --- a/pipelined/src/ifu/ifu.sv +++ b/pipelined/src/ifu/ifu.sv @@ -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; diff --git a/pipelined/src/lsu/lsu.sv b/pipelined/src/lsu/lsu.sv index 0d08e3fa..4c775107 100644 --- a/pipelined/src/lsu/lsu.sv +++ b/pipelined/src/lsu/lsu.sv @@ -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 diff --git a/pipelined/src/mmu/mmu.sv b/pipelined/src/mmu/mmu.sv index dbf23e98..da90ee2c 100644 --- a/pipelined/src/mmu/mmu.sv +++ b/pipelined/src/mmu/mmu.sv @@ -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, diff --git a/pipelined/src/mmu/pmachecker.sv b/pipelined/src/mmu/pmachecker.sv index 455f510d..df6eb271 100644 --- a/pipelined/src/mmu/pmachecker.sv +++ b/pipelined/src/mmu/pmachecker.sv @@ -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;