From fcb1c63f5f3ddb6d84038b4212ed1d01ff5f2b46 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 24 May 2023 16:12:41 -0500 Subject: [PATCH] Partial parameterization into mmu. --- src/ifu/ifu.sv | 2 +- src/lsu/lsu.sv | 138 ++++++++++++++++---------------- src/mmu/hptw.sv | 92 +++++++++++---------- src/mmu/mmu.sv | 31 ++++--- src/wally/wallypipelinedcore.sv | 2 +- 5 files changed, 130 insertions(+), 135 deletions(-) diff --git a/src/ifu/ifu.sv b/src/ifu/ifu.sv index 3d6f3e3db..73bf18dc4 100644 --- a/src/ifu/ifu.sv +++ b/src/ifu/ifu.sv @@ -170,7 +170,7 @@ module ifu import cvw::*; #(parameter cvw_t P) ( flopr #(1) StallMReg(.clk, .reset, .d(StallM), .q(StallMQ)); assign TLBFlush = sfencevmaM & ~StallMQ; - mmu #(.TLB_ENTRIES(P.ITLB_ENTRIES), .IMMU(1)) + mmu #(.P(P), .TLB_ENTRIES(P.ITLB_ENTRIES), .IMMU(1)) immu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW, .DisableTranslation(1'b0), .VAdr(PCFExt), diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index 9923a5957..607d3571b 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -29,9 +29,7 @@ // and limitations under the License. ///////////////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - -module lsu ( +module lsu import cvw::*; #(parameter cvw_t P) ( input logic clk, reset, input logic StallM, FlushM, StallW, FlushW, output logic LSUStallM, // LSU stalls pipeline during a multicycle operation @@ -46,17 +44,17 @@ module lsu ( output logic DCacheMiss, // D cache miss for performance counters output logic DCacheAccess, // D cache memory access for performance counters // address and write data - input logic [`XLEN-1:0] IEUAdrE, // Execution stage memory address - output logic [`XLEN-1:0] IEUAdrM, // Memory stage memory address - input logic [`XLEN-1:0] WriteDataM, // Write data from IEU - output logic [`LLEN-1:0] ReadDataW, // Read data to IEU or FPU + input logic [P.XLEN-1:0] IEUAdrE, // Execution stage memory address + output logic [P.XLEN-1:0] IEUAdrM, // Memory stage memory address + input logic [P.XLEN-1:0] WriteDataM, // Write data from IEU + output logic [P.LLEN-1:0] ReadDataW, // Read data to IEU or FPU // cpu privilege input logic [1:0] PrivilegeModeW, // Current privilege mode input logic BigEndianM, // Swap byte order to big endian input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries output logic DCacheStallM, // D$ busy with multicycle operation // fpu - input logic [`FLEN-1:0] FWriteDataM, // Write data from FPU + input logic [P.FLEN-1:0] FWriteDataM, // Write data from FPU input logic FpLoadStoreM, // Selects FPU as store for write data // faults output logic LoadPageFaultM, StoreAmoPageFaultM, // Page fault exceptions @@ -67,34 +65,34 @@ module lsu ( output logic StoreAmoMisalignedFaultM, // Store or AMO address misaligned fault output logic StoreAmoAccessFaultM, // Store or AMO access fault // connect to ahb - output logic [`PA_BITS-1:0] LSUHADDR, // Bus address from LSU to EBU - input logic [`XLEN-1:0] HRDATA, // Bus read data from LSU to EBU - output logic [`XLEN-1:0] LSUHWDATA, // Bus write data from LSU to EBU + output logic [P.PA_BITS-1:0] LSUHADDR, // Bus address from LSU to EBU + input logic [P.XLEN-1:0] HRDATA, // Bus read data from LSU to EBU + output logic [P.XLEN-1:0] LSUHWDATA, // Bus write data from LSU to EBU input logic LSUHREADY, // Bus ready from LSU to EBU output logic LSUHWRITE, // Bus write operation from LSU to EBU output logic [2:0] LSUHSIZE, // Bus operation size from LSU to EBU output logic [2:0] LSUHBURST, // Bus burst from LSU to EBU output logic [1:0] LSUHTRANS, // Bus transaction type from LSU to EBU - output logic [`XLEN/8-1:0] LSUHWSTRB, // Bus byte write enables from LSU to EBU + output logic [P.XLEN/8-1:0] LSUHWSTRB, // Bus byte write enables from LSU to EBU // page table walker - input logic [`XLEN-1:0] SATP_REGW, // SATP (supervisor address translation and protection) CSR + input logic [P.XLEN-1:0] SATP_REGW, // SATP (supervisor address translation and protection) CSR input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // STATUS CSR bits: make executable readable, supervisor user memory, machine privilege input logic [1:0] STATUS_MPP, // Machine previous privilege mode - input logic [`XLEN-1:0] PCSpillF, // Fetch PC + input logic [P.XLEN-1:0] PCSpillF, // Fetch PC input logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk input logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits - output logic [`XLEN-1:0] PTE, // Page table entry write to ITLB + output logic [P.XLEN-1:0] PTE, // Page table entry write to ITLB output logic [1:0] PageType, // Type of page table entry to write to ITLB output logic ITLBWriteF, // Write PTE to ITLB output logic SelHPTW, // During a HPTW walk the effective privilege mode becomes S_MODE - input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration from privileged unit - input var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0] // PMP address from privileged unit + input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration from privileged unit + input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0] // PMP address from privileged unit ); - logic [`XLEN+1:0] IEUAdrExtM; // Memory stage address zero-extended to PA_BITS or XLEN whichever is longer - logic [`XLEN+1:0] IEUAdrExtE; // Execution stage address zero-extended to PA_BITS or XLEN whichever is longer - logic [`PA_BITS-1:0] PAdrM; // Physical memory address - logic [`XLEN+1:0] IHAdrM; // Either IEU or HPTW memory address + logic [P.XLEN+1:0] IEUAdrExtM; // Memory stage address zero-extended to PA_BITS or XLEN whichever is longer + logic [P.XLEN+1:0] IEUAdrExtE; // Execution stage address zero-extended to PA_BITS or XLEN whichever is longer + logic [P.PA_BITS-1:0] PAdrM; // Physical memory address + logic [P.XLEN+1:0] IHAdrM; // Either IEU or HPTW memory address logic [1:0] PreLSURWM; // IEU or HPTW Read/Write signal logic [1:0] LSURWM; // IEU or HPTW Read/Write signal gated by LR/SC @@ -111,19 +109,19 @@ module lsu ( logic BusCommittedM; // Bus memory operation in flight, delay interrupts logic DCacheCommittedM; // D$ memory operation started, delay interrupts - logic [`LLEN-1:0] DTIMReadDataWordM; // DTIM read data - logic [`LLEN-1:0] DCacheReadDataWordM; // D$ read data - logic [`LLEN-1:0] ReadDataWordMuxM; // DTIM or D$ read data - logic [`LLEN-1:0] LittleEndianReadDataWordM; // Endian-swapped read data - logic [`LLEN-1:0] ReadDataWordM; // Read data before subword selection - logic [`LLEN-1:0] ReadDataM; // Final read data + logic [P.LLEN-1:0] DTIMReadDataWordM; // DTIM read data + logic [P.LLEN-1:0] DCacheReadDataWordM; // D$ read data + logic [P.LLEN-1:0] ReadDataWordMuxM; // DTIM or D$ read data + logic [P.LLEN-1:0] LittleEndianReadDataWordM; // Endian-swapped read data + logic [P.LLEN-1:0] ReadDataWordM; // Read data before subword selection + logic [P.LLEN-1:0] ReadDataM; // Final read data - logic [`XLEN-1:0] IHWriteDataM; // IEU or HPTW write data - logic [`XLEN-1:0] IMAWriteDataM; // IEU, HPTW, or AMO write data - logic [`LLEN-1:0] IMAFWriteDataM; // IEU, HPTW, AMO, or FPU write data - logic [`LLEN-1:0] LittleEndianWriteDataM; // Ending-swapped write data - logic [`LLEN-1:0] LSUWriteDataM; // Final write data - logic [(`LLEN-1)/8:0] ByteMaskM; // Selects which bytes within a word to write + logic [P.XLEN-1:0] IHWriteDataM; // IEU or HPTW write data + logic [P.XLEN-1:0] IMAWriteDataM; // IEU, HPTW, or AMO write data + logic [P.LLEN-1:0] IMAFWriteDataM; // IEU, HPTW, AMO, or FPU write data + logic [P.LLEN-1:0] LittleEndianWriteDataM; // Ending-swapped write data + logic [P.LLEN-1:0] LSUWriteDataM; // Final write data + logic [(P.LLEN-1)/8:0] ByteMaskM; // Selects which bytes within a word to write logic DTLBMissM; // DTLB miss causes HPTW walk logic DTLBWriteM; // Writes PTE and PageType to DTLB @@ -140,7 +138,7 @@ module lsu ( // Zero-extend address to 34 bits for XLEN=32 ///////////////////////////////////////////////////////////////////////////////////////////// - flopenrc #(`XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM); + flopenrc #(P.XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM); assign IEUAdrExtM = {2'b00, IEUAdrM}; assign IEUAdrExtE = {2'b00, IEUAdrE}; @@ -149,12 +147,12 @@ module lsu ( // MMU include PMP and is needed if any privileged supported ///////////////////////////////////////////////////////////////////////////////////////////// - if(`VIRTMEM_SUPPORTED) begin : hptw - hptw hptw(.clk, .reset, .MemRWM, .AtomicM, .ITLBMissF, .ITLBWriteF, + if(P.VIRTMEM_SUPPORTED) begin : hptw + hptw #(P) hptw(.clk, .reset, .MemRWM, .AtomicM, .ITLBMissF, .ITLBWriteF, .DTLBMissM, .DTLBWriteM, .InstrUpdateDAF, .DataUpdateDAM, .FlushW, .DCacheStallM, .SATP_REGW, .PCSpillF, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW, - .ReadDataM(ReadDataM[`XLEN-1:0]), // ReadDataM is LLEN, but HPTW only needs XLEN + .ReadDataM(ReadDataM[P.XLEN-1:0]), // ReadDataM is LLEN, but HPTW only needs XLEN .WriteDataM, .Funct3M, .LSUFunct3M, .Funct7M, .LSUFunct7M, .IEUAdrExtM, .PTE, .IHWriteDataM, .PageType, .PreLSURWM, .LSUAtomicM, .IHAdrM, .HPTWStall, .SelHPTW, @@ -184,10 +182,10 @@ module lsu ( ///////////////////////////////////////////////////////////////////////////////////////////// // MMU and misalignment fault logic required if privileged unit exists ///////////////////////////////////////////////////////////////////////////////////////////// - if(`ZICSR_SUPPORTED == 1) begin : dmmu + if(P.ZICSR_SUPPORTED == 1) begin : dmmu logic DisableTranslation; // During HPTW walk or D$ flush disable virtual memory address translation assign DisableTranslation = SelHPTW | FlushDCacheM; - mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0)) + mmu #(.P(P), .TLB_ENTRIES(P.DTLB_ENTRIES), .IMMU(0)) dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW, .DisableTranslation, .VAdr(IHAdrM), .Size(LSUFunct3M[1:0]), .PTE, .PageTypeWriteVal(PageType), .TLBWrite(DTLBWriteM), .TLBFlush(sfencevmaM), @@ -204,9 +202,9 @@ module lsu ( end else begin // No MMU, so no PMA/page faults and no address translation assign {DTLBMissM, LSULoadAccessFaultM, LSUStoreAmoAccessFaultM, LoadMisalignedFaultM, StoreAmoMisalignedFaultM} = '0; assign {LoadPageFaultM, StoreAmoPageFaultM} = '0; - assign PAdrM = IHAdrM[`PA_BITS-1:0]; + assign PAdrM = IHAdrM[P.PA_BITS-1:0]; assign CacheableM = 1'b1; - assign SelDTIM = `DTIM_SUPPORTED & ~`BUS_SUPPORTED; // if no PMA then select dtim if there is a DTIM. If there is + assign SelDTIM = P.DTIM_SUPPORTED & ~P.BUS_SUPPORTED; // if no PMA then select dtim if there is a DTIM. If there is // a bus then this is always 0. Cannot have both without PMA. end @@ -222,31 +220,31 @@ module lsu ( // Discard memory request on pipeline flush assign IgnoreRequest = IgnoreRequestTLB | FlushW; - if (`DTIM_SUPPORTED) begin : dtim - logic [`PA_BITS-1:0] DTIMAdr; + if (P.DTIM_SUPPORTED) begin : dtim + logic [P.PA_BITS-1:0] DTIMAdr; logic [1:0] DTIMMemRWM; // The DTIM uses untranslated addresses, so it is not compatible with virtual memory. - mux2 #(`PA_BITS) DTIMAdrMux(IEUAdrExtE[`PA_BITS-1:0], IEUAdrExtM[`PA_BITS-1:0], MemRWM[0], DTIMAdr); + mux2 #(P.PA_BITS) DTIMAdrMux(IEUAdrExtE[P.PA_BITS-1:0], IEUAdrExtM[P.PA_BITS-1:0], MemRWM[0], DTIMAdr); assign DTIMMemRWM = SelDTIM & ~IgnoreRequestTLB ? LSURWM : '0; // **** fix ReadDataWordM to be LLEN. ByteMask is wrong length. // **** create config to support DTIM with floating point. dtim dtim(.clk, .ce(~GatedStallW), .MemRWM(DTIMMemRWM), .DTIMAdr, .FlushW, .WriteDataM(LSUWriteDataM), - .ReadDataWordM(DTIMReadDataWordM[`XLEN-1:0]), .ByteMaskM(ByteMaskM[`XLEN/8-1:0])); + .ReadDataWordM(DTIMReadDataWordM[P.XLEN-1:0]), .ByteMaskM(ByteMaskM[P.XLEN/8-1:0])); end else begin end - if (`BUS_SUPPORTED) begin : bus - if(`DCACHE_SUPPORTED) begin : dcache - localparam LLENWORDSPERLINE = `DCACHE_LINELENINBITS/`LLEN; // Number of LLEN words in cacheline + if (P.BUS_SUPPORTED) begin : bus + if(P.DCACHE_SUPPORTED) begin : dcache + localparam LLENWORDSPERLINE = P.DCACHE_LINELENINBITS/P.LLEN; // Number of LLEN words in cacheline localparam LLENLOGBWPL = $clog2(LLENWORDSPERLINE); // Log2 of ^ - localparam BEATSPERLINE = `DCACHE_LINELENINBITS/`AHBW; // Number of AHBW words (beats) in cacheline + localparam BEATSPERLINE = P.DCACHE_LINELENINBITS/P.AHBW; // Number of AHBW words (beats) in cacheline localparam AHBWLOGBWPL = $clog2(BEATSPERLINE); // Log2 of ^ - localparam LINELEN = `DCACHE_LINELENINBITS; // Number of bits in cacheline - localparam LLENPOVERAHBW = `LLEN / `AHBW; // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation) + localparam LINELEN = P.DCACHE_LINELENINBITS; // Number of bits in cacheline + localparam LLENPOVERAHBW = P.LLEN / P.AHBW; // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation) logic [LINELEN-1:0] FetchBuffer; // Temporary buffer to hold partially fetched cacheline - logic [`PA_BITS-1:0] DCacheBusAdr; // Cacheline address to fetch or writeback. + logic [P.PA_BITS-1:0] DCacheBusAdr; // Cacheline address to fetch or writeback. logic [AHBWLOGBWPL-1:0] BeatCount; // Position within a cacheline. ahbcacheinterface to cache logic DCacheBusAck; // ahbcacheinterface completed fetch or writeback logic SelBusBeat; // ahbcacheinterface selects postion in cacheline with BeatCount @@ -263,8 +261,8 @@ module lsu ( assign CacheAtomicM = CacheableM & ~IgnoreRequestTLB & ~SelDTIM ? LSUAtomicM : '0; assign FlushDCache = FlushDCacheM & ~(IgnoreRequestTLB | SelHPTW); - cache #(.PA_BITS(`PA_BITS), .XLEN(`XLEN), .LINELEN(`DCACHE_LINELENINBITS), .NUMLINES(`DCACHE_WAYSIZEINBYTES*8/LINELEN), - .NUMWAYS(`DCACHE_NUMWAYS), .LOGBWPL(LLENLOGBWPL), .WORDLEN(`LLEN), .MUXINTERVAL(`LLEN), .READ_ONLY_CACHE(0)) dcache( + cache #(.PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.DCACHE_LINELENINBITS), .NUMLINES(P.DCACHE_WAYSIZEINBYTES*8/LINELEN), + .NUMWAYS(P.DCACHE_NUMWAYS), .LOGBWPL(LLENLOGBWPL), .WORDLEN(P.LLEN), .MUXINTERVAL(P.LLEN), .READ_ONLY_CACHE(0)) dcache( .clk, .reset, .Stall(GatedStallW), .SelBusBeat, .FlushStage(FlushW), .CacheRW(CacheRWM), .CacheAtomic(CacheAtomicM), .FlushCache(FlushDCache), .NextSet(IEUAdrE[11:0]), .PAdr(PAdrM), .ByteMask(ByteMaskM), .BeatCount(BeatCount[AHBWLOGBWPL-1:AHBWLOGBWPL-LLENLOGBWPL]), @@ -275,7 +273,7 @@ module lsu ( .FetchBuffer, .CacheBusRW, .CacheBusAck(DCacheBusAck), .InvalidateCache(1'b0)); - ahbcacheinterface #(.AHBW(`AHBW), .LLEN(`LLEN), .PA_BITS(`PA_BITS), .BEATSPERLINE(BEATSPERLINE), .AHBWLOGBWPL(AHBWLOGBWPL), .LINELEN(LINELEN), .LLENPOVERAHBW(LLENPOVERAHBW), .READ_ONLY_CACHE(0)) ahbcacheinterface( + ahbcacheinterface #(.AHBW(P.AHBW), .LLEN(P.LLEN), .PA_BITS(P.PA_BITS), .BEATSPERLINE(BEATSPERLINE), .AHBWLOGBWPL(AHBWLOGBWPL), .LINELEN(LINELEN), .LLENPOVERAHBW(LLENPOVERAHBW), .READ_ONLY_CACHE(0)) ahbcacheinterface( .HCLK(clk), .HRESETn(~reset), .Flush(FlushW), .HRDATA, .HWDATA(LSUHWDATA), .HWSTRB(LSUHWSTRB), .HSIZE(LSUHSIZE), .HBURST(LSUHBURST), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HREADY(LSUHREADY), @@ -289,25 +287,25 @@ module lsu ( // Uncache bus access may be smaller width than LLEN. Duplicate LLENPOVERAHBW times. // *** DTIMReadDataWordM should be increased to LLEN. // pma should generate exception for LLEN read to periph. - mux3 #(`LLEN) UnCachedDataMux(.d0(DCacheReadDataWordM), .d1({LLENPOVERAHBW{FetchBuffer[`XLEN-1:0]}}), - .d2({{`LLEN-`XLEN{1'b0}}, DTIMReadDataWordM[`XLEN-1:0]}), + mux3 #(P.LLEN) UnCachedDataMux(.d0(DCacheReadDataWordM), .d1({LLENPOVERAHBW{FetchBuffer[P.XLEN-1:0]}}), + .d2({{P.LLEN-P.XLEN{1'b0}}, DTIMReadDataWordM[P.XLEN-1:0]}), .s({SelDTIM, ~(CacheableOrFlushCacheM)}), .y(ReadDataWordMuxM)); end else begin : passthrough // No Cache, use simple ahbinterface instad of ahbcacheinterface logic [1:0] BusRW; // Non-DTIM memory access, ignore cacheableM - logic [`XLEN-1:0] FetchBuffer; + logic [P.XLEN-1:0] FetchBuffer; assign BusRW = ~IgnoreRequestTLB & ~SelDTIM ? LSURWM : '0; assign LSUHADDR = PAdrM; assign LSUHSIZE = LSUFunct3M; - ahbinterface #(`XLEN, 1) ahbinterface(.HCLK(clk), .HRESETn(~reset), .Flush(FlushW), .HREADY(LSUHREADY), + ahbinterface #(P.XLEN, 1) ahbinterface(.HCLK(clk), .HRESETn(~reset), .Flush(FlushW), .HREADY(LSUHREADY), .HRDATA(HRDATA), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HWDATA(LSUHWDATA), .HWSTRB(LSUHWSTRB), .BusRW, .ByteMask(ByteMaskM), .WriteData(LSUWriteDataM), .Stall(GatedStallW), .BusStall, .BusCommitted(BusCommittedM), .FetchBuffer(FetchBuffer)); // Mux between the 2 sources of read data, 0: Bus, 1: DTIM - if(`DTIM_SUPPORTED) mux2 #(`XLEN) ReadDataMux2(FetchBuffer, DTIMReadDataWordM, SelDTIM, ReadDataWordMuxM); - else assign ReadDataWordMuxM = FetchBuffer[`XLEN-1:0]; + if(P.DTIM_SUPPORTED) mux2 #(P.XLEN) ReadDataMux2(FetchBuffer, DTIMReadDataWordM, SelDTIM, ReadDataWordMuxM); + else assign ReadDataWordMuxM = FetchBuffer[P.XLEN-1:0]; assign LSUHBURST = 3'b0; assign {DCacheStallM, DCacheCommittedM, DCacheMiss, DCacheAccess} = '0; end @@ -322,16 +320,16 @@ module lsu ( ///////////////////////////////////////////////////////////////////////////////////////////// // Atomic operations ///////////////////////////////////////////////////////////////////////////////////////////// - if (`A_SUPPORTED) begin:atomic - atomic atomic(.clk, .reset, .StallW, .ReadDataM(ReadDataM[`XLEN-1:0]), .IHWriteDataM, .PAdrM, + if (P.A_SUPPORTED) begin:atomic + atomic atomic(.clk, .reset, .StallW, .ReadDataM(ReadDataM[P.XLEN-1:0]), .IHWriteDataM, .PAdrM, .LSUFunct7M, .LSUFunct3M, .LSUAtomicM, .PreLSURWM, .IgnoreRequest, .IMAWriteDataM, .SquashSCW, .LSURWM); end else begin:lrsc assign SquashSCW = 0; assign LSURWM = PreLSURWM; assign IMAWriteDataM = IHWriteDataM; end - if (`F_SUPPORTED) - mux2 #(`LLEN) datamux({{{`LLEN-`XLEN}{1'b0}}, IMAWriteDataM}, FWriteDataM, FpLoadStoreM, IMAFWriteDataM); + if (P.F_SUPPORTED) + mux2 #(P.LLEN) datamux({{{P.LLEN-P.XLEN}{1'b0}}, IMAWriteDataM}, FWriteDataM, FpLoadStoreM, IMAFWriteDataM); else assign IMAFWriteDataM = IMAWriteDataM; ///////////////////////////////////////////////////////////////////////////////////////////// @@ -342,13 +340,13 @@ module lsu ( subwordwrite subwordwrite(.LSUFunct3M, .IMAFWriteDataM, .LittleEndianWriteDataM); // Compute byte masks - swbytemask #(`LLEN) swbytemask(.Size(LSUFunct3M), .Adr(PAdrM[$clog2(`LLEN/8)-1:0]), .ByteMask(ByteMaskM)); + swbytemask #(P.LLEN) swbytemask(.Size(LSUFunct3M), .Adr(PAdrM[$clog2(P.LLEN/8)-1:0]), .ByteMask(ByteMaskM)); ///////////////////////////////////////////////////////////////////////////////////////////// // MW Pipeline Register ///////////////////////////////////////////////////////////////////////////////////////////// - flopen #(`LLEN) ReadDataMWReg(clk, ~StallW, ReadDataM, ReadDataW); + flopen #(P.LLEN) ReadDataMWReg(clk, ~StallW, ReadDataM, ReadDataW); ///////////////////////////////////////////////////////////////////////////////////////////// // Big Endian Byte Swapper @@ -356,9 +354,9 @@ module lsu ( // swap the bytes when read from big-endian memory ///////////////////////////////////////////////////////////////////////////////////////////// - if (`BIGENDIAN_SUPPORTED) begin:endian - endianswap #(`LLEN) storeswap(.BigEndianM, .a(LittleEndianWriteDataM), .y(LSUWriteDataM)); - endianswap #(`LLEN) loadswap(.BigEndianM, .a(ReadDataWordMuxM), .y(LittleEndianReadDataWordM)); + if (P.BIGENDIAN_SUPPORTED) begin:endian + endianswap #(P.LLEN) storeswap(.BigEndianM, .a(LittleEndianWriteDataM), .y(LSUWriteDataM)); + endianswap #(P.LLEN) loadswap(.BigEndianM, .a(ReadDataWordMuxM), .y(LittleEndianReadDataWordM)); end else begin assign LSUWriteDataM = LittleEndianWriteDataM; assign LittleEndianReadDataWordM = ReadDataWordMuxM; diff --git a/src/mmu/hptw.sv b/src/mmu/hptw.sv index 2cc76e8f0..e627f598d 100644 --- a/src/mmu/hptw.sv +++ b/src/mmu/hptw.sv @@ -29,20 +29,18 @@ // OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /////////////////////////////////////////// -`include "wally-config.vh" - -module hptw ( +module hptw import cvw::*; #(parameter cvw_t P) ( input logic clk, reset, - input logic [`XLEN-1:0] SATP_REGW, // includes SATP.MODE to determine number of levels in page table - input logic [`XLEN-1:0] PCSpillF, // addresses to translate - input logic [`XLEN+1:0] IEUAdrExtM, // addresses to translate + input logic [P.XLEN-1:0] SATP_REGW, // includes SATP.MODE to determine number of levels in page table + input logic [P.XLEN-1:0] PCSpillF, // addresses to translate + input logic [P.XLEN+1:0] IEUAdrExtM, // addresses to translate input logic [1:0] MemRWM, AtomicM, // system status input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, input logic [1:0] STATUS_MPP, input logic [1:0] PrivilegeModeW, - input logic [`XLEN-1:0] ReadDataM, // page table entry from LSU - input logic [`XLEN-1:0] WriteDataM, + input logic [P.XLEN-1:0] ReadDataM, // page table entry from LSU + input logic [P.XLEN-1:0] WriteDataM, input logic DCacheStallM, // stall from LSU input logic [2:0] Funct3M, input logic [6:0] Funct7M, @@ -51,12 +49,12 @@ module hptw ( input logic FlushW, input logic InstrUpdateDAF, input logic DataUpdateDAM, - output logic [`XLEN-1:0] PTE, // page table entry to TLBs + output logic [P.XLEN-1:0] PTE, // page table entry to TLBs output logic [1:0] PageType, // page type to TLBs output logic ITLBWriteF, DTLBWriteM, // write TLB with new entry output logic [1:0] PreLSURWM, - output logic [`XLEN+1:0] IHAdrM, - output logic [`XLEN-1:0] IHWriteDataM, + output logic [P.XLEN+1:0] IHAdrM, + output logic [P.XLEN-1:0] IHWriteDataM, output logic [1:0] LSUAtomicM, output logic [2:0] LSUFunct3M, output logic [6:0] LSUFunct7M, @@ -74,8 +72,8 @@ module hptw ( LEAF, IDLE, UPDATE_PTE} statetype; logic DTLBWalk; // register TLBs translation miss requests - logic [`PPN_BITS-1:0] BasePageTablePPN; - logic [`PPN_BITS-1:0] CurrentPPN; + logic [P.PPN_BITS-1:0] BasePageTablePPN; + logic [P.PPN_BITS-1:0] CurrentPPN; logic Executable, Writable, Readable, Valid, PTE_U; logic Misaligned, MegapageMisaligned; logic ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE; @@ -83,18 +81,18 @@ module hptw ( logic TLBMiss; logic PRegEn; logic [1:0] NextPageType; - logic [`SVMODE_BITS-1:0] SvMode; - logic [`XLEN-1:0] TranslationVAdr; - logic [`XLEN-1:0] NextPTE; + logic [P.SVMODE_BITS-1:0] SvMode; + logic [P.XLEN-1:0] TranslationVAdr; + logic [P.XLEN-1:0] NextPTE; logic UpdatePTE; logic HPTWUpdateDA; - logic [`PA_BITS-1:0] HPTWReadAdr; + logic [P.PA_BITS-1:0] HPTWReadAdr; logic SelHPTWAdr; - logic [`XLEN+1:0] HPTWAdrExt; + logic [P.XLEN+1:0] HPTWAdrExt; logic ITLBMissOrUpdateDAF; logic DTLBMissOrUpdateDAM; logic LSUAccessFaultM; - logic [`PA_BITS-1:0] HPTWAdr; + logic [P.PA_BITS-1:0] HPTWAdr; logic [1:0] HPTWRW; logic [2:0] HPTWSize; // 32 or 64 bit access statetype WalkerState, NextWalkerState, InitialWalkerState; @@ -119,18 +117,18 @@ module hptw ( assign HPTWInstrAccessFaultF = TakeHPTWFaultDelay ? HPTWInstrAccessFaultDelay : 1'b0; // Extract bits from CSRs and inputs - assign SvMode = SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]; - assign BasePageTablePPN = SATP_REGW[`PPN_BITS-1:0]; + assign SvMode = SATP_REGW[P.XLEN-1:P.XLEN-P.SVMODE_BITS]; + assign BasePageTablePPN = SATP_REGW[P.PPN_BITS-1:0]; assign TLBMiss = (DTLBMissOrUpdateDAM | ITLBMissOrUpdateDAF); // Determine which address to translate - mux2 #(`XLEN) vadrmux(PCSpillF, IEUAdrExtM[`XLEN-1:0], DTLBWalk, TranslationVAdr); - assign CurrentPPN = PTE[`PPN_BITS+9:10]; + mux2 #(P.XLEN) vadrmux(PCSpillF, IEUAdrExtM[P.XLEN-1:0], DTLBWalk, TranslationVAdr); + assign CurrentPPN = PTE[P.PPN_BITS+9:10]; // State flops flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissOrUpdateDAM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB) assign PRegEn = HPTWRW[1] & ~DCacheStallM | UpdatePTE; - flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, NextPTE, PTE); // Capture page table entry from data cache + flopenr #(P.XLEN) PTEReg(clk, reset, PRegEn, NextPTE, PTE); // Capture page table entry from data cache // Assign PTE descriptors common across all XLEN values // For non-leaf PTEs, D, A, U bits are reserved and ignored. They do not cause faults while walking the page table @@ -140,7 +138,7 @@ module hptw ( assign ValidLeafPTE = ValidPTE & LeafPTE; assign ValidNonLeafPTE = ValidPTE & ~LeafPTE; - if(`SVADU_SUPPORTED) begin : hptwwrites + if(P.SVADU_SUPPORTED) begin : hptwwrites logic ReadAccess, WriteAccess; logic InvalidRead, InvalidWrite, InvalidOp; logic UpperBitsUnequal; @@ -148,18 +146,18 @@ module hptw ( logic [1:0] EffectivePrivilegeMode; logic ImproperPrivilege; logic SaveHPTWAdr, SelHPTWWriteAdr; - logic [`PA_BITS-1:0] HPTWWriteAdr; + logic [P.PA_BITS-1:0] HPTWWriteAdr; logic SetDirty; logic Dirty, Accessed; - logic [`XLEN-1:0] AccessedPTE; + logic [P.XLEN-1:0] AccessedPTE; - assign AccessedPTE = {PTE[`XLEN-1:8], (SetDirty | PTE[7]), 1'b1, PTE[5:0]}; // set accessed bit, conditionally set dirty bit - mux2 #(`XLEN) NextPTEMux(ReadDataM, AccessedPTE, UpdatePTE, NextPTE); - flopenr #(`PA_BITS) HPTWAdrWriteReg(clk, reset, SaveHPTWAdr, HPTWReadAdr, HPTWWriteAdr); + assign AccessedPTE = {PTE[P.XLEN-1:8], (SetDirty | PTE[7]), 1'b1, PTE[5:0]}; // set accessed bit, conditionally set dirty bit + mux2 #(P.XLEN) NextPTEMux(ReadDataM, AccessedPTE, UpdatePTE, NextPTE); + flopenr #(P.PA_BITS) HPTWAdrWriteReg(clk, reset, SaveHPTWAdr, HPTWReadAdr, HPTWWriteAdr); assign SaveHPTWAdr = WalkerState == L0_ADR; assign SelHPTWWriteAdr = UpdatePTE | HPTWRW[0]; - mux2 #(`PA_BITS) HPTWWriteAdrMux(HPTWReadAdr, HPTWWriteAdr, SelHPTWWriteAdr, HPTWAdr); + mux2 #(P.PA_BITS) HPTWWriteAdrMux(HPTWReadAdr, HPTWWriteAdr, SelHPTWWriteAdr, HPTWAdr); assign {Dirty, Accessed} = PTE[7:6]; assign WriteAccess = MemRWM[0]; // implies | (|AtomicM); @@ -167,11 +165,11 @@ module hptw ( assign ReadAccess = MemRWM[1]; assign EffectivePrivilegeMode = DTLBWalk ? (STATUS_MPRV ? STATUS_MPP : PrivilegeModeW) : PrivilegeModeW; // DTLB uses MPP mode when MPRV is 1 - assign ImproperPrivilege = ((EffectivePrivilegeMode == `U_MODE) & ~PTE_U) | - ((EffectivePrivilegeMode == `S_MODE) & PTE_U & (~STATUS_SUM & DTLBWalk)); + assign ImproperPrivilege = ((EffectivePrivilegeMode == P.U_MODE) & ~PTE_U) | + ((EffectivePrivilegeMode == P.S_MODE) & PTE_U & (~STATUS_SUM & DTLBWalk)); // Check for page faults - vm64check vm64check(.SATP_MODE(SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]), .VAdr(TranslationVAdr), + vm64check vm64check(.SATP_MODE(SATP_REGW[P.XLEN-1:P.XLEN-P.SVMODE_BITS]), .VAdr(TranslationVAdr), .SV39Mode(), .UpperBitsUnequal); assign InvalidRead = ReadAccess & ~Readable & (~STATUS_MXR | ~Executable); assign InvalidWrite = WriteAccess & ~Writable; @@ -212,16 +210,16 @@ module hptw ( endcase // HPTWAdr muxing - if (`XLEN==32) begin // RV32 + if (P.XLEN==32) begin // RV32 logic [9:0] VPN; - logic [`PPN_BITS-1:0] PPN; + logic [P.PPN_BITS-1:0] PPN; assign VPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? TranslationVAdr[31:22] : TranslationVAdr[21:12]; // select VPN field based on HPTW state assign PPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? BasePageTablePPN : CurrentPPN; assign HPTWReadAdr = {PPN, VPN, 2'b00}; assign HPTWSize = 3'b010; end else begin // RV64 logic [8:0] VPN; - logic [`PPN_BITS-1:0] PPN; + logic [P.PPN_BITS-1:0] PPN; always_comb case (WalkerState) // select VPN field based on HPTW state L3_ADR, L3_RD: VPN = TranslationVAdr[47:39]; @@ -230,19 +228,19 @@ module hptw ( default: VPN = TranslationVAdr[20:12]; endcase assign PPN = ((WalkerState == L3_ADR) | (WalkerState == L3_RD) | - (SvMode != `SV48 & ((WalkerState == L2_ADR) | (WalkerState == L2_RD)))) ? BasePageTablePPN : CurrentPPN; + (SvMode != P.SV48 & ((WalkerState == L2_ADR) | (WalkerState == L2_RD)))) ? BasePageTablePPN : CurrentPPN; assign HPTWReadAdr = {PPN, VPN, 3'b000}; assign HPTWSize = 3'b011; end // Initial state and misalignment for RV32/64 - if (`XLEN == 32) begin + if (P.XLEN == 32) begin assign InitialWalkerState = L1_ADR; assign MegapageMisaligned = |(CurrentPPN[9:0]); // must have zero PPN0 assign Misaligned = ((WalkerState == L0_ADR) & MegapageMisaligned); end else begin logic GigapageMisaligned, TerapageMisaligned; - assign InitialWalkerState = (SvMode == `SV48) ? L3_ADR : L2_ADR; + assign InitialWalkerState = (SvMode == P.SV48) ? L3_ADR : L2_ADR; assign TerapageMisaligned = |(CurrentPPN[26:0]); // must have zero PPN2, PPN1, PPN0 assign GigapageMisaligned = |(CurrentPPN[17:0]); // must have zero PPN1 and PPN0 assign MegapageMisaligned = |(CurrentPPN[8:0]); // must have zero PPN0 @@ -281,7 +279,7 @@ module hptw ( L0_RD: if (DCacheStallM) NextWalkerState = L0_RD; else if(LSUAccessFaultM) NextWalkerState = IDLE; else NextWalkerState = LEAF; - LEAF: if (`SVADU_SUPPORTED & HPTWUpdateDA) NextWalkerState = UPDATE_PTE; + LEAF: if (P.SVADU_SUPPORTED & HPTWUpdateDA) NextWalkerState = UPDATE_PTE; else NextWalkerState = IDLE; UPDATE_PTE: if(DCacheStallM) NextWalkerState = UPDATE_PTE; else NextWalkerState = LEAF; @@ -293,8 +291,8 @@ module hptw ( assign HPTWAccessFaultDelay = HPTWLoadAccessFaultDelay | HPTWStoreAmoAccessFaultDelay | HPTWInstrAccessFaultDelay; assign HPTWStall = (WalkerState != IDLE) | (WalkerState == IDLE & TLBMiss & ~(HPTWAccessFaultDelay)); - assign ITLBMissOrUpdateDAF = ITLBMissF | (`SVADU_SUPPORTED & InstrUpdateDAF); - assign DTLBMissOrUpdateDAM = DTLBMissM | (`SVADU_SUPPORTED & DataUpdateDAM); + assign ITLBMissOrUpdateDAF = ITLBMissF | (P.SVADU_SUPPORTED & InstrUpdateDAF); + assign DTLBMissOrUpdateDAM = DTLBMissM | (P.SVADU_SUPPORTED & DataUpdateDAM); // HTPW address/data/control muxing @@ -304,15 +302,15 @@ module hptw ( // always block interrupts when using the hardware page table walker. // multiplex the outputs to LSU - if(`XLEN == 64) assign HPTWAdrExt = {{(`XLEN+2-`PA_BITS){1'b0}}, HPTWAdr}; // extend to 66 bits + if(P.XLEN == 64) assign HPTWAdrExt = {{(P.XLEN+2-P.PA_BITS){1'b0}}, HPTWAdr}; // extend to 66 bits else assign HPTWAdrExt = HPTWAdr; mux2 #(2) rwmux(MemRWM, HPTWRW, SelHPTW, PreLSURWM); mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LSUFunct3M); mux2 #(7) funct7mux(Funct7M, 7'b0, SelHPTW, LSUFunct7M); mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LSUAtomicM); - mux2 #(`XLEN+2) lsupadrmux(IEUAdrExtM, HPTWAdrExt, SelHPTWAdr, IHAdrM); - if(`SVADU_SUPPORTED) - mux2 #(`XLEN) lsuwritedatamux(WriteDataM, PTE, SelHPTW, IHWriteDataM); + mux2 #(P.XLEN+2) lsupadrmux(IEUAdrExtM, HPTWAdrExt, SelHPTWAdr, IHAdrM); + if(P.SVADU_SUPPORTED) + mux2 #(P.XLEN) lsuwritedatamux(WriteDataM, PTE, SelHPTW, IHWriteDataM); else assign IHWriteDataM = WriteDataM; endmodule diff --git a/src/mmu/mmu.sv b/src/mmu/mmu.sv index 380787e6b..517b16860 100644 --- a/src/mmu/mmu.sv +++ b/src/mmu/mmu.sv @@ -26,24 +26,23 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`include "wally-config.vh" - -module mmu #(parameter TLB_ENTRIES = 8, IMMU = 0) ( +module mmu import cvw::*; #(parameter cvw_t P, + parameter TLB_ENTRIES = 8, IMMU = 0) ( input logic clk, reset, - input logic [`XLEN-1:0] SATP_REGW, // Current value of satp CSR (from privileged unit) + input logic [P.XLEN-1:0] SATP_REGW, // Current value of satp CSR (from privileged unit) input logic STATUS_MXR, // Status CSR: make executable page readable input logic STATUS_SUM, // Status CSR: Supervisor access to user memory input logic STATUS_MPRV, // Status CSR: modify machine privilege input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor input logic DisableTranslation, // virtual address translation disabled during D$ flush and HPTW walk that use physical addresses - input logic [`XLEN+1:0] VAdr, // virtual/physical address from IEU or physical address from HPTW + input logic [P.XLEN+1:0] VAdr, // virtual/physical address from IEU or physical address from HPTW input logic [1:0] Size, // access size: 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits - input logic [`XLEN-1:0] PTE, // page table entry + input logic [P.XLEN-1:0] PTE, // page table entry input logic [1:0] PageTypeWriteVal, // page type input logic TLBWrite, // write TLB entry input logic TLBFlush, // Invalidate all TLB entries - output logic [`PA_BITS-1:0] PhysicalAddress, // PAdr when no translation, or translated VAdr (TLBPAdr) when there is translation + output logic [P.PA_BITS-1:0] PhysicalAddress, // PAdr when no translation, or translated VAdr (TLBPAdr) when there is translation output logic TLBMiss, // Miss TLB output logic Cacheable, // PMA indicates memory address is cachable output logic Idempotent, // PMA indicates memory address is idempotent @@ -55,11 +54,11 @@ module mmu #(parameter TLB_ENTRIES = 8, IMMU = 0) ( output logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned fault sources // PMA checker signals input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // access type - input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration - input var logic [`PA_BITS-3:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0] // PMP addresses + input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration + input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0] // PMP addresses ); - logic [`PA_BITS-1:0] TLBPAdr; // physical address for TLB + logic [P.PA_BITS-1:0] TLBPAdr; // physical address for TLB logic PMAInstrAccessFaultF; // Instruction access fault from PMA logic PMPInstrAccessFaultF; // Instruction access fault from PMP logic PMALoadAccessFaultM; // Load access fault from PMA @@ -73,15 +72,15 @@ module mmu #(parameter TLB_ENTRIES = 8, IMMU = 0) ( logic ReadNoAmoAccessM; // Read that is not part of atomic operation causes Load faults. Otherwise StoreAmo faults // only instantiate TLB if Virtual Memory is supported - if (`VIRTMEM_SUPPORTED) begin:tlb + if (P.VIRTMEM_SUPPORTED) begin:tlb logic ReadAccess, WriteAccess; assign ReadAccess = ExecuteAccessF | ReadAccessM; // execute also acts as a TLB read. Execute and Read are never active for the same MMU, so safe to mix pipestages assign WriteAccess = WriteAccessM; tlb #(.TLB_ENTRIES(TLB_ENTRIES), .ITLB(IMMU)) tlb( .clk, .reset, - .SATP_MODE(SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS]), - .SATP_ASID(SATP_REGW[`ASID_BASE+`ASID_BITS-1:`ASID_BASE]), - .VAdr(VAdr[`XLEN-1:0]), .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, + .SATP_MODE(SATP_REGW[P.XLEN-1:P.XLEN-P.SVMODE_BITS]), + .SATP_ASID(SATP_REGW[P.ASID_BASE+P.ASID_BITS-1:P.ASID_BASE]), + .VAdr(VAdr[P.XLEN-1:0]), .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW, .ReadAccess, .WriteAccess, .DisableTranslation, .PTE, .PageTypeWriteVal, .TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit, @@ -96,7 +95,7 @@ module mmu #(parameter TLB_ENTRIES = 8, IMMU = 0) ( // If translation is occuring, select translated physical address from TLB // the lower 12 bits are the page offset. These are never changed from the orginal // non translated address. - mux2 #(`PA_BITS-12) addressmux(VAdr[`PA_BITS-1:12], TLBPAdr[`PA_BITS-1:12], Translate, PhysicalAddress[`PA_BITS-1:12]); + mux2 #(P.PA_BITS-12) addressmux(VAdr[P.PA_BITS-1:12], TLBPAdr[P.PA_BITS-1:12], Translate, PhysicalAddress[P.PA_BITS-1:12]); assign PhysicalAddress[11:0] = VAdr[11:0]; /////////////////////////////////////////// @@ -108,7 +107,7 @@ module mmu #(parameter TLB_ENTRIES = 8, IMMU = 0) ( .Cacheable, .Idempotent, .SelTIM, .PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM); - if (`PMP_ENTRIES > 0) begin : pmp + if (P.PMP_ENTRIES > 0) begin : pmp pmpchecker pmpchecker(.PhysicalAddress, .PrivilegeModeW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index 05be8cfa1..95b57c848 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -208,7 +208,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .FCvtIntStallD, .LoadStallD, .MDUStallD, .CSRRdStallD, .PCSrcE, .CSRReadM, .CSRWriteM, .PrivilegedM, .CSRWriteFenceM, .InvalidateICacheM, .StoreStallD); - lsu lsu( + lsu #(P) lsu( .clk, .reset, .StallM, .FlushM, .StallW, .FlushW, // CPU interface .MemRWM, .Funct3M, .Funct7M(InstrM[31:25]), .AtomicM,