python: Add a PrivateL1CacheHierarchy to the gem5 components
This adds a private L1 classic cache hierarchy to the gem5 components. Change-Id: I78b038e2a4031d6df78ac9908f7baf9cb5920f47 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49305 Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Jason Lowe-Power <power.jg@gmail.com> Maintainer: Jason Lowe-Power <power.jg@gmail.com>
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
# Copyright (c) 2021 The Regents of the University of California
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met: redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer;
|
||||
# redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution;
|
||||
# neither the name of the copyright holders nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from ..abstract_cache_hierarchy import AbstractCacheHierarchy
|
||||
from .abstract_classic_cache_hierarchy import AbstractClassicCacheHierarchy
|
||||
from .caches.l1dcache import L1DCache
|
||||
from .caches.l1icache import L1ICache
|
||||
from .caches.mmu_cache import MMUCache
|
||||
from ...boards.abstract_board import AbstractBoard
|
||||
from ...isas import ISA
|
||||
from ...runtime import get_runtime_isa
|
||||
|
||||
from m5.objects import Cache, BaseXBar, SystemXBar, BadAddr, Port
|
||||
|
||||
from ...utils.override import *
|
||||
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class PrivateL1CacheHierarchy(AbstractClassicCacheHierarchy):
|
||||
"""
|
||||
A cache setup where each core has a private L1 data and instruction Cache.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def _get_default_membus() -> SystemXBar:
|
||||
"""
|
||||
A method used to obtain the default memory bus of 64 bit in width for
|
||||
the PrivateL1CacheHierarchy.
|
||||
|
||||
:returns: The default memory bus for the PrivateL1PrivateL2
|
||||
CacheHierarchy.
|
||||
"""
|
||||
membus = SystemXBar(width=64)
|
||||
membus.badaddr_responder = BadAddr()
|
||||
membus.default = membus.badaddr_responder.pio
|
||||
return membus
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
l1d_size: str,
|
||||
l1i_size: str,
|
||||
membus: Optional[BaseXBar] = _get_default_membus.__func__(),
|
||||
) -> None:
|
||||
"""
|
||||
:param l1d_size: The size of the L1 Data Cache (e.g., "32kB").
|
||||
|
||||
:param l1i_size: The size of the L1 Instruction Cache (e.g., "32kB").
|
||||
|
||||
:param membus: The memory bus. This parameter is optional parameter and
|
||||
will default to a 64 bit width SystemXBar is not specified.
|
||||
"""
|
||||
|
||||
AbstractClassicCacheHierarchy.__init__(self=self)
|
||||
self.membus = membus
|
||||
self._l1d_size = l1d_size
|
||||
self._l1i_size = l1i_size
|
||||
|
||||
@overrides(AbstractClassicCacheHierarchy)
|
||||
def get_mem_side_port(self) -> Port:
|
||||
return self.membus.mem_side_ports
|
||||
|
||||
@overrides(AbstractClassicCacheHierarchy)
|
||||
def get_cpu_side_port(self) -> Port:
|
||||
return self.membus.cpu_side_ports
|
||||
|
||||
@overrides(AbstractCacheHierarchy)
|
||||
def incorporate_cache(self, board: AbstractBoard) -> None:
|
||||
|
||||
# Set up the system port for functional access from the simulator.
|
||||
board.connect_system_port(self.membus.cpu_side_ports)
|
||||
|
||||
for cntr in board.get_memory().get_memory_controllers():
|
||||
cntr.port = self.membus.mem_side_ports
|
||||
|
||||
self.l1icaches = [
|
||||
L1ICache(size=self._l1i_size)
|
||||
for i in range(board.get_processor().get_num_cores())
|
||||
]
|
||||
|
||||
self.l1dcaches = [
|
||||
L1DCache(size=self._l1i_size)
|
||||
for i in range(board.get_processor().get_num_cores())
|
||||
]
|
||||
# ITLB Page walk caches
|
||||
self.iptw_caches = [
|
||||
MMUCache(size="8KiB") for _ in range(board.get_processor().get_num_cores())
|
||||
]
|
||||
# DTLB Page walk caches
|
||||
self.dptw_caches = [
|
||||
MMUCache(size="8KiB") for _ in range(board.get_processor().get_num_cores())
|
||||
]
|
||||
|
||||
if board.has_coherent_io():
|
||||
self._setup_io_cache(board)
|
||||
|
||||
for i, cpu in enumerate(board.get_processor().get_cores()):
|
||||
|
||||
cpu.connect_icache(self.l1icaches[i].cpu_side)
|
||||
cpu.connect_dcache(self.l1dcaches[i].cpu_side)
|
||||
|
||||
self.l1icaches[i].mem_side = self.membus.cpu_side_ports
|
||||
self.l1dcaches[i].mem_side = self.membus.cpu_side_ports
|
||||
|
||||
self.iptw_caches[i].mem_side = self.membus.cpu_side_ports
|
||||
self.dptw_caches[i].mem_side = self.membus.cpu_side_ports
|
||||
|
||||
cpu.connect_walker_ports(
|
||||
self.iptw_caches[i].cpu_side, self.dptw_caches[i].cpu_side
|
||||
)
|
||||
|
||||
if get_runtime_isa() == ISA.X86:
|
||||
int_req_port = self.membus.mem_side_ports
|
||||
int_resp_port = self.membus.cpu_side_ports
|
||||
cpu.connect_interrupt(int_req_port, int_resp_port)
|
||||
else:
|
||||
cpu.connect_interrupt()
|
||||
|
||||
def _setup_io_cache(self, board: AbstractBoard) -> None:
|
||||
"""Create a cache for coherent I/O connections"""
|
||||
self.iocache = Cache(
|
||||
assoc=8,
|
||||
tag_latency=50,
|
||||
data_latency=50,
|
||||
response_latency=50,
|
||||
mshrs=20,
|
||||
size="1kB",
|
||||
tgts_per_mshr=12,
|
||||
addr_ranges=board.mem_ranges,
|
||||
)
|
||||
self.iocache.mem_side = self.membus.cpu_side_ports
|
||||
self.iocache.cpu_side = board.get_mem_side_coherent_io_port()
|
||||
Reference in New Issue
Block a user