diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index 4848b5ebb..bb23f4fd3 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -185,7 +185,7 @@ module ifu import cvw::*; #(parameter cvw_t P) ( .TLBFlush, .PhysicalAddress(PCPF), .TLBMiss(ITLBMissF), - .Cacheable(CacheableF), .Idempotent(), .SelTIM(SelIROM), + .Cacheable(CacheableF), .Idempotent(), .AllowShift(), .SelTIM(SelIROM), .InstrAccessFaultF, .LoadAccessFaultM(), .StoreAmoAccessFaultM(), .InstrPageFaultF, .LoadPageFaultM(), .StoreAmoPageFaultM(), .LoadMisalignedFaultM(), .StoreAmoMisalignedFaultM(), diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index 12ab9930e..053d2bbb0 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -119,6 +119,7 @@ module lsu import cvw::*; #(parameter cvw_t P) ( logic SelSpillE; // Align logic detected a spill and needs to stall logic CacheableM; // PMA indicates memory address is cacheable + logic AllowShiftM; // PMA: indicates if WriteData should be byte shifted before going to cache or bus by offset. logic BusCommittedM; // Bus memory operation in flight, delay interrupts logic DCacheCommittedM; // D$ memory operation started, delay interrupts @@ -244,7 +245,7 @@ module lsu import cvw::*; #(parameter cvw_t P) ( dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE, .PrivilegeModeW, .DisableTranslation, .VAdr(IHAdrM), .Size(LSUFunct3M[1:0]), .PTE, .PageTypeWriteVal(PageType), .TLBWrite(DTLBWriteM), .TLBFlush(sfencevmaM), - .PhysicalAddress(PAdrM), .TLBMiss(DTLBMissM), .Cacheable(CacheableM), .Idempotent(), .SelTIM(SelDTIM), + .PhysicalAddress(PAdrM), .TLBMiss(DTLBMissM), .Cacheable(CacheableM), .Idempotent(), .AllowShift(AllowShiftM), .SelTIM(SelDTIM), .InstrAccessFaultF(), .LoadAccessFaultM(LSULoadAccessFaultM), .StoreAmoAccessFaultM(LSUStoreAmoAccessFaultM), .InstrPageFaultF(), .LoadPageFaultM(LSULoadPageFaultM), .StoreAmoPageFaultM(LSUStoreAmoPageFaultM), @@ -426,7 +427,7 @@ module lsu import cvw::*; #(parameter cvw_t P) ( if(MISALIGN_SUPPORT) begin subwordreaddouble #(P.LLEN) subwordread(.ReadDataWordMuxM(LittleEndianReadDataWordM), .PAdrM(PAdrM[2:0]), .BigEndianM, .FpLoadStoreM, .Funct3M(LSUFunct3M), .ReadDataM); - subwordwritedouble #(P.LLEN) subwordwrite(.LSUFunct3M, .PAdrM(PAdrM[2:0]), .FpLoadStoreM, .BigEndianM, .CacheableM, .IMAFWriteDataM, .LittleEndianWriteDataM); + subwordwritedouble #(P.LLEN) subwordwrite(.LSUFunct3M, .PAdrM(PAdrM[2:0]), .FpLoadStoreM, .BigEndianM, .AllowShiftM, .IMAFWriteDataM, .LittleEndianWriteDataM); end else begin subwordread #(P.LLEN) subwordread(.ReadDataWordMuxM(LittleEndianReadDataWordM), .PAdrM(PAdrM[2:0]), .BigEndianM, .FpLoadStoreM, .Funct3M(LSUFunct3M), .ReadDataM); diff --git a/src/lsu/subwordwritedouble.sv b/src/lsu/subwordwritedouble.sv index 599d71984..eb62aa106 100644 --- a/src/lsu/subwordwritedouble.sv +++ b/src/lsu/subwordwritedouble.sv @@ -33,7 +33,7 @@ module subwordwritedouble #(parameter LLEN) ( input logic [2:0] PAdrM, input logic FpLoadStoreM, input logic BigEndianM, - input logic CacheableM, + input logic AllowShiftM, input logic [LLEN-1:0] IMAFWriteDataM, output logic [LLEN*2-1:0] LittleEndianWriteDataM ); @@ -48,8 +48,8 @@ module subwordwritedouble #(parameter LLEN) ( // 10: PAdrM[2:0] // 11: BigEndianPAdr // 00: 00000 - // 01: 00111 - mux4 #(5) OffsetMux(5'b0, 5'b11111, {2'b0, PAdrM}, BigEndianPAdr, {CacheableM, BigEndianM}, PAdrSwap); + // 01: 11111 + mux4 #(5) OffsetMux(5'b0, 5'b11111, {2'b0, PAdrM}, BigEndianPAdr, {AllowShiftM, BigEndianM}, PAdrSwap); //assign PAdrSwap = BigEndianM ? BigEndianPAdr : {2'b0, PAdrM}; /* verilator lint_off WIDTHEXPAND */ /* verilator lint_off WIDTHTRUNC */ diff --git a/src/mmu/mmu.sv b/src/mmu/mmu.sv index e842016a2..80a1ca7da 100644 --- a/src/mmu/mmu.sv +++ b/src/mmu/mmu.sv @@ -49,6 +49,7 @@ module mmu import cvw::*; #(parameter cvw_t P, output logic TLBMiss, // Miss TLB output logic Cacheable, // PMA indicates memory address is cachable output logic Idempotent, // PMA indicates memory address is idempotent + output logic AllowShift, // PMA indicates if WriteData should be byte shifted before going to cache or bus by offset output logic SelTIM, // Select a tightly integrated memory // Faults output logic InstrAccessFaultF, LoadAccessFaultM, StoreAmoAccessFaultM, // access fault sources @@ -112,7 +113,7 @@ module mmu import cvw::*; #(parameter cvw_t P, pmachecker #(P) pmachecker(.PhysicalAddress, .Size, .CMOpM, .AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .PBMemoryType, - .Cacheable, .Idempotent, .SelTIM, + .Cacheable, .Idempotent, .AllowShift, .SelTIM, .PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM); if (P.PMP_ENTRIES > 0) begin : pmp diff --git a/src/mmu/pmachecker.sv b/src/mmu/pmachecker.sv index 84e41ba65..60296213d 100644 --- a/src/mmu/pmachecker.sv +++ b/src/mmu/pmachecker.sv @@ -1,4 +1,4 @@ -/////////////////////////////////////////// +////////////////////////////////////////// // pmachecker.sv // // Written: tfleming@hmc.edu & jtorrey@hmc.edu 20 April 2021 @@ -38,7 +38,7 @@ module pmachecker import cvw::*; #(parameter cvw_t P) ( input logic WriteAccessM, // Write access input logic ReadAccessM, // Read access input logic [1:0] PBMemoryType, // PBMT field of PTE during TLB hit, or 00 otherwise - output logic Cacheable, Idempotent, SelTIM, + output logic Cacheable, Idempotent, AllowShift, SelTIM, output logic PMAInstrAccessFaultF, output logic PMALoadAccessFaultM, output logic PMAStoreAmoAccessFaultM @@ -60,7 +60,8 @@ module pmachecker import cvw::*; #(parameter cvw_t P) ( // Only non-core RAM/ROM memory regions are cacheable. PBMT can override cachable; NC and IO are uncachable assign CacheableRegion = SelRegions[3] | SelRegions[4] | SelRegions[5]; // exclusion-tag: unused-cachable - assign Cacheable = (PBMemoryType == 2'b00) ? CacheableRegion : 0; + assign Cacheable = (PBMemoryType == 2'b00) ? CacheableRegion : 0; + assign AllowShift = SelRegions[1] | SelRegions[2] | SelRegions[3] | SelRegions[5] | SelRegions[6]; // Nonidemdempotent means access could have side effect and must not be done speculatively or redundantly // I/O is nonidempotent. PBMT can override PMA; NC is idempotent and IO is non-idempotent