From cb5f676ea015d0d545b0a54c4220de4ba9cbd7a7 Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Mon, 16 Aug 2021 15:58:43 -0700 Subject: [PATCH] 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 Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power --- .../classic/private_l1_cache_hierarchy.py | 155 ++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 components_library/cachehierarchies/classic/private_l1_cache_hierarchy.py diff --git a/components_library/cachehierarchies/classic/private_l1_cache_hierarchy.py b/components_library/cachehierarchies/classic/private_l1_cache_hierarchy.py new file mode 100644 index 0000000000..15a0160505 --- /dev/null +++ b/components_library/cachehierarchies/classic/private_l1_cache_hierarchy.py @@ -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()