2023-01-11 23:15:07 +00:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
2021-06-23 05:41:00 +00:00
// lsu.sv
//
2023-01-11 23:15:07 +00:00
// Written: David_Harris@hmc.edu, ross1728@gmail.com
// Created: 9 January 2021
// Modified: 11 January 2023
2021-06-23 05:41:00 +00:00
//
// Purpose: Load/Store Unit
2023-01-12 00:52:46 +00:00
// HPTW, DMMU, data cache, interface to external bus
// Atomic, Endian swap, and subword read/write logic
//
// Documentation: RISC-V System on Chip Design Chapter 9 (Figure 9.2)
//
2023-01-11 23:15:08 +00:00
// A component of the CORE-V-WALLY configurable RISC-V project.
2021-06-23 05:41:00 +00:00
//
2023-01-10 19:35:20 +00:00
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
2021-06-23 05:41:00 +00:00
//
2023-01-10 19:35:20 +00:00
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
2021-06-23 05:41:00 +00:00
//
2023-01-10 19:35:20 +00:00
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
2021-06-23 05:41:00 +00:00
//
2023-01-10 19:35:20 +00:00
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
2023-01-11 23:15:07 +00:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////
2021-06-23 05:41:00 +00:00
2023-05-24 21:12:41 +00:00
module lsu import cvw : : * ; # ( parameter cvw_t P ) (
2023-06-12 20:29:18 +00:00
input logic clk , reset ,
input logic StallM , FlushM , StallW , FlushW ,
output logic LSUStallM , // LSU stalls pipeline during a multicycle operation
2023-01-16 02:23:09 +00:00
// connected to cpu (controls)
2023-12-13 16:39:01 +00:00
input logic [ 1 : 0 ] MemRWE , // Read/Write control
2023-06-12 20:29:18 +00:00
input logic [ 1 : 0 ] MemRWM , // Read/Write control
input logic [ 2 : 0 ] Funct3M , // Size of memory operation
input logic [ 6 : 0 ] Funct7M , // Atomic memory operation function
input logic [ 1 : 0 ] AtomicM , // Atomic memory operation
input logic FlushDCacheM , // Flush D cache to next level of memory
2023-07-02 17:55:35 +00:00
input logic [ 3 : 0 ] CMOpM , // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero
2023-11-21 07:37:56 +00:00
input logic LSUPrefetchM , // Prefetch; presently unused
2023-06-12 20:29:18 +00:00
output logic CommittedM , // Delay interrupts while memory operation in flight
output logic SquashSCW , // Store conditional failed disable write to GPR
output logic DCacheMiss , // D cache miss for performance counters
output logic DCacheAccess , // D cache memory access for performance counters
2023-01-16 02:23:09 +00:00
// address and write data
2023-06-12 20:29:18 +00:00
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
2023-01-16 02:23:09 +00:00
// cpu privilege
2023-06-12 20:29:18 +00:00
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
2023-01-16 02:23:09 +00:00
// fpu
2023-06-12 20:29:18 +00:00
input logic [ P . FLEN - 1 : 0 ] FWriteDataM , // Write data from FPU
input logic FpLoadStoreM , // Selects FPU as store for write data
2023-01-16 02:23:09 +00:00
// faults
2023-06-12 20:29:18 +00:00
output logic LoadPageFaultM , StoreAmoPageFaultM , // Page fault exceptions
output logic LoadMisalignedFaultM , // Load address misaligned fault
output logic LoadAccessFaultM , // Load access fault (PMA)
output logic HPTWInstrAccessFaultF , // HPTW generated access fault during instruction fetch
2024-01-05 22:23:12 +00:00
output logic HPTWInstrPageFaultF , // HPTW generated access fault during instruction fetch
2023-01-16 02:23:09 +00:00
// cpu hazard unit (trap)
2023-06-12 20:29:18 +00:00
output logic StoreAmoMisalignedFaultM , // Store or AMO address misaligned fault
output logic StoreAmoAccessFaultM , // Store or AMO access fault
2023-01-23 23:27:39 +00:00
// connect to ahb
2023-06-12 20:29:18 +00:00
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 [ P . XLEN / 8 - 1 : 0 ] LSUHWSTRB , // Bus byte write enables from LSU to EBU
2023-01-23 23:27:39 +00:00
// page table walker
2023-06-12 20:29:18 +00:00
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
2023-08-26 01:33:08 +00:00
input logic ENVCFG_PBMTE , // Page-based memory types enabled
2023-12-13 19:49:04 +00:00
input logic ENVCFG_ADUE , // HPTW A/D Update enable
2023-06-12 20:29:18 +00:00
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 [ 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 [ 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
2023-01-16 02:23:09 +00:00
) ;
2023-11-15 16:19:50 +00:00
localparam logic MISALIGN_SUPPORT = P . ZICCLSM_SUPPORTED & P . DCACHE_SUPPORTED ;
2023-11-15 16:30:48 +00:00
localparam MLEN = MISALIGN_SUPPORT ? 2 * P . LLEN : P . LLEN ; // widen buffer for misaligned accessess
2021-07-06 15:41:36 +00:00
2023-05-24 21:12:41 +00:00
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
2023-01-12 00:52:46 +00:00
2023-06-12 20:29:18 +00:00
logic [ 1 : 0 ] PreLSURWM ; // IEU or HPTW Read/Write signal
logic [ 1 : 0 ] LSURWM ; // IEU or HPTW Read/Write signal gated by LR/SC
logic [ 2 : 0 ] LSUFunct3M ; // IEU or HPTW memory operation size
logic [ 6 : 0 ] LSUFunct7M ; // AMO function gated by HPTW
logic [ 1 : 0 ] LSUAtomicM ; // AMO signal gated by HPTW
2023-01-12 00:52:46 +00:00
2023-06-12 20:29:18 +00:00
logic GatedStallW ; // Hazard unit StallW gated when SelHPTW = 1
2023-03-24 22:32:25 +00:00
2023-06-12 20:29:18 +00:00
logic BusStall ; // Bus interface busy with multicycle operation
logic HPTWStall ; // HPTW busy with multicycle operation
2023-10-27 18:55:16 +00:00
logic CacheBusHPWTStall ; // Cache, bus, or hptw is requesting a stall
logic SelSpillE ; // Align logic detected a spill and needs to stall
2023-01-12 00:52:46 +00:00
2023-06-12 20:29:18 +00:00
logic CacheableM ; // PMA indicates memory address is cacheable
logic BusCommittedM ; // Bus memory operation in flight, delay interrupts
logic DCacheCommittedM ; // D$ memory operation started, delay interrupts
2023-01-12 00:52:46 +00:00
2023-05-24 21:12:41 +00:00
logic [ P . LLEN - 1 : 0 ] DTIMReadDataWordM ; // DTIM read data
2023-10-27 18:55:16 +00:00
/* verilator lint_off WIDTHEXPAND */
2023-11-15 16:19:50 +00:00
logic [ MLEN - 1 : 0 ] DCacheReadDataWordM ; // D$ read data
logic [ MLEN - 1 : 0 ] LSUWriteDataSpillM ; // Final write data
logic [ MLEN / 8 - 1 : 0 ] ByteMaskSpillM ; // Selects which bytes within a word to write
2023-10-27 18:55:16 +00:00
/* verilator lint_on WIDTHEXPAND */
logic [ P . LLEN - 1 : 0 ] DCacheReadDataWordSpillM ; // D$ read data
2023-05-24 21:12:41 +00:00
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
2023-01-12 00:52:46 +00:00
2023-05-24 21:12:41 +00:00
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
2023-10-30 20:47:46 +00:00
logic [ ( P . LLEN - 1 ) / 8 : 0 ] ByteMaskExtendedM ; // Selects which bytes within a word to write
2023-11-01 19:25:18 +00:00
logic [ 1 : 0 ] MemRWSpillM ;
logic SpillStallM ;
logic SelStoreDelay ;
2023-06-12 20:29:18 +00:00
logic DTLBMissM ; // DTLB miss causes HPTW walk
logic DTLBWriteM ; // Writes PTE and PageType to DTLB
logic DataUpdateDAM ; // DTLB hit needs to update dirty or access bits
logic LSULoadAccessFaultM ; // Load acces fault
logic LSUStoreAmoAccessFaultM ; // Store access fault
logic IgnoreRequestTLB ; // On either ITLB or DTLB miss, ignore miss so HPTW can handle
logic IgnoreRequest ; // On FlushM or TLB miss ignore memory operation
logic SelDTIM ; // Select DTIM rather than bus or D$
2023-11-27 20:59:42 +00:00
logic [ P . XLEN - 1 : 0 ] WriteDataZM ;
2024-01-05 22:23:12 +00:00
logic LSULoadPageFaultM , LSUStoreAmoPageFaultM ;
2023-11-27 20:59:42 +00:00
2023-01-12 00:52:46 +00:00
/////////////////////////////////////////////////////////////////////////////////////////////
// Pipeline for IEUAdr E to M
// Zero-extend address to 34 bits for XLEN=32
/////////////////////////////////////////////////////////////////////////////////////////////
2023-05-24 21:12:41 +00:00
flopenrc # ( P . XLEN ) AddressMReg ( clk , reset , FlushM , ~ StallM , IEUAdrE , IEUAdrM ) ;
2023-10-27 18:55:16 +00:00
if ( MISALIGN_SUPPORT ) begin : ziccslm_align
2023-10-30 20:30:09 +00:00
logic [ P . XLEN - 1 : 0 ] IEUAdrSpillE , IEUAdrSpillM ;
2023-10-27 18:55:16 +00:00
align # ( P ) align ( . clk , . reset , . StallM , . FlushM , . IEUAdrE , . IEUAdrM , . Funct3M ,
2023-11-28 20:19:30 +00:00
. MemRWM ,
2023-11-28 20:21:37 +00:00
. DCacheReadDataWordM , . CacheBusHPWTStall , . SelHPTW ,
2023-10-30 20:47:46 +00:00
. ByteMaskM , . ByteMaskExtendedM , . LSUWriteDataM , . ByteMaskSpillM , . LSUWriteDataSpillM ,
2023-11-28 20:19:30 +00:00
. IEUAdrSpillE , . IEUAdrSpillM , . SelSpillE , . DCacheReadDataWordSpillM , . SpillStallM ,
2023-11-01 19:25:18 +00:00
. SelStoreDelay ) ;
2023-10-27 18:55:16 +00:00
assign IEUAdrExtM = { 2 'b00 , IEUAdrSpillM } ;
assign IEUAdrExtE = { 2 'b00 , IEUAdrSpillE } ;
end else begin : no_ziccslm_align
assign IEUAdrExtM = { 2 'b00 , IEUAdrM } ;
assign IEUAdrExtE = { 2 'b00 , IEUAdrE } ;
assign SelSpillE = '0 ;
assign DCacheReadDataWordSpillM = DCacheReadDataWordM ;
2023-10-30 19:00:49 +00:00
assign ByteMaskSpillM = ByteMaskM ;
assign LSUWriteDataSpillM = LSUWriteDataM ;
2023-11-01 19:25:18 +00:00
assign MemRWSpillM = MemRWM ;
2023-11-10 22:08:04 +00:00
assign { SpillStallM , SelStoreDelay } = '0 ;
2023-10-27 18:55:16 +00:00
end
2022-01-31 18:11:42 +00:00
2023-11-27 20:59:42 +00:00
if ( P . ZICBOZ_SUPPORTED ) begin : cboz
mux2 # ( P . XLEN ) writedatacbozmux ( WriteDataM , '0 , CMOpM [ 3 ] , WriteDataZM ) ;
end else begin : cboz
assign WriteDataZM = WriteDataM ;
end
2022-01-31 18:11:42 +00:00
/////////////////////////////////////////////////////////////////////////////////////////////
2023-01-12 00:52:46 +00:00
// HPTW (only needed if VM supported)
2022-01-31 18:11:42 +00:00
// MMU include PMP and is needed if any privileged supported
/////////////////////////////////////////////////////////////////////////////////////////////
2022-01-05 16:25:08 +00:00
2023-05-24 21:12:41 +00:00
if ( P . VIRTMEM_SUPPORTED ) begin : hptw
hptw # ( P ) hptw ( . clk , . reset , . MemRWM , . AtomicM , . ITLBMissF , . ITLBWriteF ,
2023-02-27 01:51:45 +00:00
. DTLBMissM , . DTLBWriteM , . InstrUpdateDAF , . DataUpdateDAM ,
2023-03-06 23:50:57 +00:00
. FlushW , . DCacheStallM , . SATP_REGW , . PCSpillF ,
2023-12-13 19:49:04 +00:00
. STATUS_MXR , . STATUS_SUM , . STATUS_MPRV , . STATUS_MPP , . ENVCFG_ADUE , . PrivilegeModeW ,
2023-05-24 21:12:41 +00:00
. ReadDataM ( ReadDataM [ P . XLEN - 1 : 0 ] ) , // ReadDataM is LLEN, but HPTW only needs XLEN
2023-11-27 20:59:42 +00:00
. WriteDataM ( WriteDataZM ) , . Funct3M , . LSUFunct3M , . Funct7M , . LSUFunct7M ,
2022-11-13 18:27:48 +00:00
. IEUAdrExtM , . PTE , . IHWriteDataM , . PageType , . PreLSURWM , . LSUAtomicM ,
2022-12-11 21:48:00 +00:00
. IHAdrM , . HPTWStall , . SelHPTW ,
2022-11-29 22:28:14 +00:00
. IgnoreRequestTLB , . LSULoadAccessFaultM , . LSUStoreAmoAccessFaultM ,
2024-01-05 22:23:12 +00:00
. LoadAccessFaultM , . StoreAmoAccessFaultM , . HPTWInstrAccessFaultF ,
. LoadPageFaultM , . StoreAmoPageFaultM , . LSULoadPageFaultM , . LSUStoreAmoPageFaultM , . HPTWInstrPageFaultF
) ;
2023-01-12 00:52:46 +00:00
end else begin // No HPTW, so signals are not multiplexed
2022-12-11 21:48:00 +00:00
assign PreLSURWM = MemRWM ;
2022-09-13 16:47:39 +00:00
assign IHAdrM = IEUAdrExtM ;
2023-01-12 00:52:46 +00:00
assign LSUFunct3M = Funct3M ;
2023-11-24 04:29:10 +00:00
assign LSUFunct7M = Funct7M ;
assign LSUAtomicM = AtomicM ;
2023-11-27 20:59:42 +00:00
assign IHWriteDataM = WriteDataZM ;
2022-11-29 22:28:14 +00:00
assign LoadAccessFaultM = LSULoadAccessFaultM ;
2024-01-05 22:23:12 +00:00
assign StoreAmoAccessFaultM = LSUStoreAmoAccessFaultM ;
assign LoadPageFaultM = LSULoadPageFaultM ;
assign StoreAmoPageFaultM = LSUStoreAmoPageFaultM ;
2023-01-12 00:52:46 +00:00
assign { HPTWStall , SelHPTW , PTE , PageType , DTLBWriteM , ITLBWriteF , IgnoreRequestTLB } = '0 ;
2024-01-05 22:23:12 +00:00
assign { HPTWInstrAccessFaultF , HPTWInstrPageFaultF } = '0 ;
2022-01-15 00:24:16 +00:00
end
2021-07-04 18:49:38 +00:00
2023-01-12 00:52:46 +00:00
// CommittedM indicates the cache, bus, or HPTW are busy with a multiple cycle operation.
// CommittedM is 1 after the first cycle and until the last cycle. Partially completed memory
// operations delay interrupts until the next instruction by suppressing pending interrupts in
// the trap module.
2021-12-29 17:21:44 +00:00
assign CommittedM = SelHPTW | DCacheCommittedM | BusCommittedM ;
2022-12-11 21:52:51 +00:00
assign GatedStallW = StallW & ~ SelHPTW ;
2023-12-29 22:06:30 +00:00
assign CacheBusHPWTStall = DCacheStallM | HPTWStall | BusStall ;
2023-11-01 19:25:18 +00:00
assign LSUStallM = CacheBusHPWTStall | SpillStallM ;
2021-12-28 22:14:10 +00:00
2023-01-12 00:52:46 +00:00
/////////////////////////////////////////////////////////////////////////////////////////////
// MMU and misalignment fault logic required if privileged unit exists
/////////////////////////////////////////////////////////////////////////////////////////////
2023-05-24 21:12:41 +00:00
if ( P . ZICSR_SUPPORTED = = 1 ) begin : dmmu
2023-01-12 00:52:46 +00:00
logic DisableTranslation ; // During HPTW walk or D$ flush disable virtual memory address translation
2023-08-18 20:59:39 +00:00
logic WriteAccessM ;
2022-02-19 20:38:17 +00:00
assign DisableTranslation = SelHPTW | FlushDCacheM ;
2023-11-27 23:44:11 +00:00
assign WriteAccessM = PreLSURWM [ 0 ] ;
2023-05-24 21:12:41 +00:00
mmu # ( . P ( P ) , . TLB_ENTRIES ( P . DTLB_ENTRIES ) , . IMMU ( 0 ) )
2023-12-13 19:49:04 +00:00
dmmu ( . clk , . reset , . SATP_REGW , . STATUS_MXR , . STATUS_SUM , . STATUS_MPRV , . STATUS_MPP , . ENVCFG_PBMTE , . ENVCFG_ADUE ,
2023-01-12 00:52:46 +00:00
. PrivilegeModeW , . DisableTranslation , . VAdr ( IHAdrM ) , . Size ( LSUFunct3M [ 1 : 0 ] ) ,
. PTE , . PageTypeWriteVal ( PageType ) , . TLBWrite ( DTLBWriteM ) , . TLBFlush ( sfencevmaM ) ,
. PhysicalAddress ( PAdrM ) , . TLBMiss ( DTLBMissM ) , . Cacheable ( CacheableM ) , . Idempotent ( ) , . SelTIM ( SelDTIM ) ,
. InstrAccessFaultF ( ) , . LoadAccessFaultM ( LSULoadAccessFaultM ) ,
2024-01-05 22:23:12 +00:00
. StoreAmoAccessFaultM ( LSUStoreAmoAccessFaultM ) , . InstrPageFaultF ( ) , . LoadPageFaultM ( LSULoadPageFaultM ) ,
. StoreAmoPageFaultM ( LSUStoreAmoPageFaultM ) ,
2022-03-22 21:52:07 +00:00
. LoadMisalignedFaultM , . StoreAmoMisalignedFaultM , // *** these faults need to be supressed during hptw.
2023-12-25 13:57:41 +00:00
. UpdateDA ( DataUpdateDAM ) , . CMOpM ( CMOpM ) ,
2022-02-19 20:38:17 +00:00
. AtomicAccessM ( | LSUAtomicM ) , . ExecuteAccessF ( 1 'b0 ) ,
2023-08-18 20:59:39 +00:00
. WriteAccessM , . ReadAccessM ( PreLSURWM [ 1 ] ) ,
2022-01-28 20:02:05 +00:00
. PMPCFG_ARRAY_REGW , . PMPADDR_ARRAY_REGW ) ;
2022-01-05 16:25:08 +00:00
2023-01-12 00:52:46 +00:00
end else begin // No MMU, so no PMA/page faults and no address translation
2022-11-29 22:28:14 +00:00
assign { DTLBMissM , LSULoadAccessFaultM , LSUStoreAmoAccessFaultM , LoadMisalignedFaultM , StoreAmoMisalignedFaultM } = '0 ;
2024-01-05 22:23:12 +00:00
assign { LSULoadPageFaultM , LSUStoreAmoPageFaultM } = '0 ;
2023-05-24 21:12:41 +00:00
assign PAdrM = IHAdrM [ P . PA_BITS - 1 : 0 ] ;
2023-01-12 00:52:46 +00:00
assign CacheableM = 1 'b1 ;
2023-05-24 21:12:41 +00:00
assign SelDTIM = P . DTIM_SUPPORTED & ~ P . BUS_SUPPORTED ; // if no PMA then select dtim if there is a DTIM. If there is
2022-10-11 19:05:20 +00:00
// a bus then this is always 0. Cannot have both without PMA.
2022-01-05 16:25:08 +00:00
end
2021-07-04 18:49:38 +00:00
2022-01-31 18:11:42 +00:00
/////////////////////////////////////////////////////////////////////////////////////////////
2023-01-12 00:52:46 +00:00
// Memory System (options)
// 1. DTIM
// 2. DTIM and bus
// 3. Bus
// 4. Cache and bus
2022-01-31 18:11:42 +00:00
/////////////////////////////////////////////////////////////////////////////////////////////
2023-01-12 00:52:46 +00:00
// Pause IEU memory request if TLB miss. After TLB fill, replay request.
// Discard memory request on pipeline flush
2022-11-07 21:03:43 +00:00
assign IgnoreRequest = IgnoreRequestTLB | FlushW ;
2022-02-05 04:30:04 +00:00
2023-05-24 21:12:41 +00:00
if ( P . DTIM_SUPPORTED ) begin : dtim
logic [ P . PA_BITS - 1 : 0 ] DTIMAdr ;
2023-06-12 20:29:18 +00:00
logic [ 1 : 0 ] DTIMMemRWM ;
2022-10-05 19:51:02 +00:00
2022-08-27 03:12:03 +00:00
// The DTIM uses untranslated addresses, so it is not compatible with virtual memory.
2023-12-29 22:06:30 +00:00
mux2 # ( P . PA_BITS ) DTIMAdrMux ( IEUAdrExtE [ P . PA_BITS - 1 : 0 ] , IEUAdrExtM [ P . PA_BITS - 1 : 0 ] , MemRWM [ 0 ] , DTIMAdr ) ;
2022-11-07 21:03:43 +00:00
assign DTIMMemRWM = SelDTIM & ~ IgnoreRequestTLB ? LSURWM : '0 ;
2022-11-01 20:23:24 +00:00
// **** fix ReadDataWordM to be LLEN. ByteMask is wrong length.
// **** create config to support DTIM with floating point.
2023-10-27 14:35:44 +00:00
// Add support for cboz
2023-12-14 02:32:14 +00:00
dtim # ( P ) dtim ( . clk , . reset , . ce ( ~ GatedStallW ) , . MemRWE ( MemRWE ) , // *** update when you update the cache RWE
. MemRWM ( DTIMMemRWM ) ,
2023-01-19 00:44:30 +00:00
. DTIMAdr , . FlushW , . WriteDataM ( LSUWriteDataM ) ,
2023-12-29 22:06:30 +00:00
. ReadDataWordM ( DTIMReadDataWordM [ P . LLEN - 1 : 0 ] ) , . ByteMaskM ( ByteMaskM ) ) ;
2022-08-27 12:31:56 +00:00
end
2023-05-24 21:12:41 +00:00
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
2023-06-12 20:29:18 +00:00
localparam LLENLOGBWPL = $clog2 ( LLENWORDSPERLINE ) ; // Log2 of ^
2023-05-24 21:12:41 +00:00
localparam BEATSPERLINE = P . DCACHE_LINELENINBITS / P . AHBW ; // Number of AHBW words (beats) in cacheline
2023-06-12 20:29:18 +00:00
localparam AHBWLOGBWPL = $clog2 ( BEATSPERLINE ) ; // Log2 of ^
localparam LINELEN = P . DCACHE_LINELENINBITS ; // Number of bits in cacheline
2023-05-24 21:12:41 +00:00
localparam LLENPOVERAHBW = P . LLEN / P . AHBW ; // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation)
2023-10-27 18:07:23 +00:00
localparam CACHEWORDLEN = P . ZICCLSM_SUPPORTED ? 2 * P . LLEN : P . LLEN ; // Width of the cache's input and output data buses. Misaligned doubles width for fast access
2023-01-18 22:47:40 +00:00
2023-06-12 20:29:18 +00:00
logic [ LINELEN - 1 : 0 ] FetchBuffer ; // Temporary buffer to hold partially fetched cacheline
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
logic [ 1 : 0 ] CacheBusRW ; // Cache sends request to ahbcacheinterface
logic [ 1 : 0 ] BusRW ; // Uncached bus memory access
logic CacheableOrFlushCacheM ; // Memory address is cacheable or operation is a cache flush
logic [ 1 : 0 ] CacheRWM ; // Cache read (10), write (01), AMO (11)
logic FlushDCache ; // Suppress d cache flush if there is an ITLB miss.
2023-07-21 18:06:27 +00:00
logic CacheStall ;
logic [ 1 : 0 ] CacheBusRWTemp ;
2023-11-28 03:24:30 +00:00
logic BusCMOZero ;
2023-12-29 17:11:06 +00:00
logic [ 3 : 0 ] CacheCMOpM ;
2023-12-29 21:07:20 +00:00
logic BusAtomic ;
2023-11-27 23:44:11 +00:00
if ( P . ZICBOZ_SUPPORTED ) begin
2023-11-28 03:24:30 +00:00
assign BusCMOZero = CMOpM [ 3 ] & ~ CacheableM ;
2024-01-02 18:16:20 +00:00
assign CacheCMOpM = ( CacheableM & ~ SelHPTW ) ? CMOpM : '0 ;
2023-12-29 21:07:20 +00:00
assign BusAtomic = AtomicM [ 1 ] & ~ CacheableM ;
2023-11-27 23:44:11 +00:00
end else begin
2023-11-28 03:24:30 +00:00
assign BusCMOZero = '0 ;
2023-12-29 21:07:20 +00:00
assign CacheCMOpM = '0 ;
assign BusAtomic = '0 ;
2023-11-27 23:44:11 +00:00
end
2023-11-28 03:24:30 +00:00
assign BusRW = ~ CacheableM & ~ SelDTIM ? LSURWM : '0 ;
2022-10-17 17:34:14 +00:00
assign CacheableOrFlushCacheM = CacheableM | FlushDCacheM ;
2023-07-21 18:06:27 +00:00
assign CacheRWM = CacheableM & ~ SelDTIM ? LSURWM : '0 ;
assign FlushDCache = FlushDCacheM & ~ ( SelHPTW ) ;
2022-11-01 20:23:24 +00:00
2023-06-15 18:42:24 +00:00
cache # ( . P ( P ) , . PA_BITS ( P . PA_BITS ) , . XLEN ( P . XLEN ) , . LINELEN ( P . DCACHE_LINELENINBITS ) , . NUMLINES ( P . DCACHE_WAYSIZEINBYTES * 8 / LINELEN ) ,
2023-10-27 18:07:23 +00:00
. NUMWAYS ( P . DCACHE_NUMWAYS ) , . LOGBWPL ( LLENLOGBWPL ) , . WORDLEN ( CACHEWORDLEN ) , . MUXINTERVAL ( P . LLEN ) , . READ_ONLY_CACHE ( 0 ) ) dcache (
2023-12-29 22:10:27 +00:00
. clk , . reset , . Stall ( GatedStallW & ~ SelSpillE ) , . SelBusBeat , . FlushStage ( FlushW | IgnoreRequestTLB ) ,
2023-12-13 16:39:01 +00:00
. CacheRW ( SelStoreDelay ? 2 'b00 : CacheRWM ) ,
2023-10-27 18:55:16 +00:00
. FlushCache ( FlushDCache ) , . NextSet ( IEUAdrExtE [ 11 : 0 ] ) , . PAdr ( PAdrM ) ,
2023-10-30 19:00:49 +00:00
. ByteMask ( ByteMaskSpillM ) , . BeatCount ( BeatCount [ AHBWLOGBWPL - 1 : AHBWLOGBWPL - LLENLOGBWPL ] ) ,
. CacheWriteData ( LSUWriteDataSpillM ) , . SelHPTW ,
2023-07-21 18:06:27 +00:00
. CacheStall , . CacheMiss ( DCacheMiss ) , . CacheAccess ( DCacheAccess ) ,
2022-11-01 20:23:24 +00:00
. CacheCommitted ( DCacheCommittedM ) ,
2022-10-05 19:51:02 +00:00
. CacheBusAdr ( DCacheBusAdr ) , . ReadDataWord ( DCacheReadDataWordM ) ,
2023-07-21 18:06:27 +00:00
. FetchBuffer , . CacheBusRW ( CacheBusRWTemp ) ,
2023-12-29 21:13:18 +00:00
. CacheBusAck ( DCacheBusAck ) , . InvalidateCache ( 1 'b0 ) , . CMOpM ( CacheCMOpM ) ) ;
2023-07-21 18:06:27 +00:00
assign DCacheStallM = CacheStall & ~ IgnoreRequestTLB ;
2023-07-21 21:31:26 +00:00
assign CacheBusRW = CacheBusRWTemp ;
2023-01-12 01:06:03 +00:00
2023-10-27 14:35:44 +00:00
// *** add support for cboz
2023-05-24 21:12:41 +00:00
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 (
2023-07-21 21:31:26 +00:00
. HCLK ( clk ) , . HRESETn ( ~ reset ) , . Flush ( FlushW | IgnoreRequestTLB ) ,
2022-11-11 20:30:32 +00:00
. HRDATA , . HWDATA ( LSUHWDATA ) , . HWSTRB ( LSUHWSTRB ) ,
2022-08-30 15:58:07 +00:00
. HSIZE ( LSUHSIZE ) , . HBURST ( LSUHBURST ) , . HTRANS ( LSUHTRANS ) , . HWRITE ( LSUHWRITE ) , . HREADY ( LSUHREADY ) ,
2023-10-27 18:55:16 +00:00
. BeatCount , . SelBusBeat , . CacheReadDataWordM ( DCacheReadDataWordM [ P . LLEN - 1 : 0 ] ) , . WriteDataM ( LSUWriteDataM ) ,
2023-12-29 21:07:20 +00:00
. Funct3 ( LSUFunct3M ) , . HADDR ( LSUHADDR ) , . CacheBusAdr ( DCacheBusAdr ) , . CacheBusRW , . BusAtomic , . BusCMOZero , . CacheableOrFlushCacheM ,
2022-09-13 16:47:39 +00:00
. CacheBusAck ( DCacheBusAck ) , . FetchBuffer , . PAdr ( PAdrM ) ,
2022-12-11 21:52:51 +00:00
. Cacheable ( CacheableOrFlushCacheM ) , . BusRW , . Stall ( GatedStallW ) ,
2022-08-26 00:54:04 +00:00
. BusStall , . BusCommitted ( BusCommittedM ) ) ;
2023-03-24 22:32:25 +00:00
// Mux between the 3 sources of read data, 0: cache, 1: Bus, 2: DTIM
// Uncache bus access may be smaller width than LLEN. Duplicate LLENPOVERAHBW times.
2023-01-12 01:06:03 +00:00
// *** DTIMReadDataWordM should be increased to LLEN.
// pma should generate exception for LLEN read to periph.
2023-10-27 18:55:16 +00:00
mux3 # ( P . LLEN ) UnCachedDataMux ( . d0 ( DCacheReadDataWordSpillM ) , . d1 ( { LLENPOVERAHBW { FetchBuffer [ P . XLEN - 1 : 0 ] } } ) ,
2023-05-24 21:12:41 +00:00
. d2 ( { { P . LLEN - P . XLEN { 1 'b0 } } , DTIMReadDataWordM [ P . XLEN - 1 : 0 ] } ) ,
2022-10-17 17:34:14 +00:00
. s ( { SelDTIM , ~ ( CacheableOrFlushCacheM ) } ) , . y ( ReadDataWordMuxM ) ) ;
2023-01-12 01:06:03 +00:00
end else begin : passthrough // No Cache, use simple ahbinterface instad of ahbcacheinterface
logic [ 1 : 0 ] BusRW ; // Non-DTIM memory access, ignore cacheableM
2023-05-24 21:12:41 +00:00
logic [ P . XLEN - 1 : 0 ] FetchBuffer ;
2022-11-07 21:03:43 +00:00
assign BusRW = ~ IgnoreRequestTLB & ~ SelDTIM ? LSURWM : '0 ;
2022-08-31 16:21:02 +00:00
2022-09-13 16:47:39 +00:00
assign LSUHADDR = PAdrM ;
2022-08-26 03:02:38 +00:00
assign LSUHSIZE = LSUFunct3M ;
2022-08-26 00:54:04 +00:00
2023-05-24 21:12:41 +00:00
ahbinterface # ( P . XLEN , 1 ) ahbinterface ( . HCLK ( clk ) , . HRESETn ( ~ reset ) , . Flush ( FlushW ) , . HREADY ( LSUHREADY ) ,
2022-08-31 19:45:01 +00:00
. HRDATA ( HRDATA ) , . HTRANS ( LSUHTRANS ) , . HWRITE ( LSUHWRITE ) , . HWDATA ( LSUHWDATA ) ,
2023-10-30 20:47:46 +00:00
. HWSTRB ( LSUHWSTRB ) , . BusRW , . ByteMask ( ByteMaskM ) , . WriteData ( LSUWriteDataM [ P . XLEN - 1 : 0 ] ) ,
2022-12-11 21:52:51 +00:00
. Stall ( GatedStallW ) , . BusStall , . BusCommitted ( BusCommittedM ) , . FetchBuffer ( FetchBuffer ) ) ;
2022-10-05 19:51:02 +00:00
2023-03-24 22:32:25 +00:00
// Mux between the 2 sources of read data, 0: Bus, 1: DTIM
2023-07-26 20:08:01 +00:00
if ( P . DTIM_SUPPORTED ) mux2 # ( P . XLEN ) ReadDataMux2 ( FetchBuffer , DTIMReadDataWordM [ P . XLEN - 1 : 0 ] , SelDTIM , ReadDataWordMuxM [ P . XLEN - 1 : 0 ] ) ;
2023-05-24 21:12:41 +00:00
else assign ReadDataWordMuxM = FetchBuffer [ P . XLEN - 1 : 0 ] ;
2022-08-26 01:30:46 +00:00
assign LSUHBURST = 3 'b0 ;
2023-01-20 18:29:25 +00:00
assign { DCacheStallM , DCacheCommittedM , DCacheMiss , DCacheAccess } = '0 ;
2022-08-27 02:58:04 +00:00
end
2023-01-12 01:06:03 +00:00
end else begin : nobus // block: bus, only DTIM
2022-08-26 01:15:59 +00:00
assign LSUHWDATA = '0 ;
2022-10-05 20:46:53 +00:00
assign ReadDataWordMuxM = DTIMReadDataWordM ;
2022-08-26 01:52:42 +00:00
assign { BusStall , BusCommittedM } = '0 ;
assign { DCacheMiss , DCacheAccess } = '0 ;
2023-01-20 18:29:25 +00:00
assign { DCacheStallM , DCacheCommittedM } = '0 ;
2022-01-13 23:00:46 +00:00
end
2022-01-14 23:55:27 +00:00
2022-01-31 18:11:42 +00:00
/////////////////////////////////////////////////////////////////////////////////////////////
2022-01-14 23:55:27 +00:00
// Atomic operations
2022-01-31 18:11:42 +00:00
/////////////////////////////////////////////////////////////////////////////////////////////
2023-06-12 20:29:18 +00:00
2023-05-24 21:12:41 +00:00
if ( P . A_SUPPORTED ) begin : atomic
2023-05-26 15:47:09 +00:00
atomic # ( P ) atomic ( . clk , . reset , . StallW , . ReadDataM ( ReadDataM [ P . XLEN - 1 : 0 ] ) , . IHWriteDataM , . PAdrM ,
2022-02-10 17:27:15 +00:00
. LSUFunct7M , . LSUFunct3M , . LSUAtomicM , . PreLSURWM , . IgnoreRequest ,
2022-08-23 15:34:39 +00:00
. IMAWriteDataM , . SquashSCW , . LSURWM ) ;
2022-01-14 23:55:27 +00:00
end else begin : lrsc
2022-11-13 18:27:48 +00:00
assign SquashSCW = 0 ; assign LSURWM = PreLSURWM ; assign IMAWriteDataM = IHWriteDataM ;
2022-01-14 23:55:27 +00:00
end
2022-03-11 00:44:50 +00:00
2023-05-24 21:12:41 +00:00
if ( P . F_SUPPORTED )
mux2 # ( P . LLEN ) datamux ( { { { P . LLEN - P . XLEN } { 1 'b0 } } , IMAWriteDataM } , FWriteDataM , FpLoadStoreM , IMAFWriteDataM ) ;
2022-08-23 15:34:39 +00:00
else assign IMAFWriteDataM = IMAWriteDataM ;
2022-05-08 06:46:35 +00:00
/////////////////////////////////////////////////////////////////////////////////////////////
// Subword Accesses
/////////////////////////////////////////////////////////////////////////////////////////////
2023-06-12 20:29:18 +00:00
2023-05-26 16:22:44 +00:00
subwordread # ( P . LLEN ) subwordread ( . ReadDataWordMuxM ( LittleEndianReadDataWordM ) , . PAdrM ( PAdrM [ 2 : 0 ] ) , . BigEndianM ,
2023-03-24 22:32:25 +00:00
. FpLoadStoreM , . Funct3M ( LSUFunct3M ) , . ReadDataM ) ;
2023-05-26 16:26:09 +00:00
subwordwrite # ( P . LLEN ) subwordwrite ( . LSUFunct3M , . IMAFWriteDataM , . LittleEndianWriteDataM ) ;
2022-08-02 01:48:45 +00:00
// Compute byte masks
2023-10-30 20:47:46 +00:00
swbytemask # ( P . LLEN , P . ZICCLSM_SUPPORTED ) swbytemask ( . Size ( LSUFunct3M ) , . Adr ( PAdrM [ $clog2 ( P . LLEN / 8 ) - 1 : 0 ] ) , . ByteMask ( ByteMaskM ) , . ByteMaskExtended ( ByteMaskExtendedM ) ) ;
2022-06-20 22:53:13 +00:00
/////////////////////////////////////////////////////////////////////////////////////////////
// MW Pipeline Register
/////////////////////////////////////////////////////////////////////////////////////////////
2023-05-24 21:12:41 +00:00
flopen # ( P . LLEN ) ReadDataMWReg ( clk , ~ StallW , ReadDataM , ReadDataW ) ;
2022-05-08 06:46:35 +00:00
/////////////////////////////////////////////////////////////////////////////////////////////
// Big Endian Byte Swapper
// hart works little-endian internally
// swap the bytes when read from big-endian memory
/////////////////////////////////////////////////////////////////////////////////////////////
2022-10-11 23:08:02 +00:00
2023-05-24 21:12:41 +00:00
if ( P . BIGENDIAN_SUPPORTED ) begin : endian
endianswap # ( P . LLEN ) storeswap ( . BigEndianM , . a ( LittleEndianWriteDataM ) , . y ( LSUWriteDataM ) ) ;
endianswap # ( P . LLEN ) loadswap ( . BigEndianM , . a ( ReadDataWordMuxM ) , . y ( LittleEndianReadDataWordM ) ) ;
2022-05-08 06:46:35 +00:00
end else begin
2022-08-23 15:34:39 +00:00
assign LSUWriteDataM = LittleEndianWriteDataM ;
2022-10-05 20:46:53 +00:00
assign LittleEndianReadDataWordM = ReadDataWordMuxM ;
2022-05-08 06:46:35 +00:00
end
2021-06-23 05:41:00 +00:00
endmodule