| # 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 ..abstract_two_level_cache_hierarchy import AbstractTwoLevelCacheHierarchy |
| from .caches.l1dcache import L1DCache |
| from .caches.l1icache import L1ICache |
| from .caches.l2cache import L2Cache |
| from ...boards.abstract_board import AbstractBoard |
| from ...isas import ISA |
| from ...runtime import get_runtime_isa |
| |
| from m5.objects import L2XBar, BaseXBar, SystemXBar, BadAddr, Port |
| |
| from ...utils.override import * |
| |
| from typing import Optional |
| |
| |
| class PrivateL1PrivateL2CacheHierarchy( |
| AbstractClassicCacheHierarchy, AbstractTwoLevelCacheHierarchy |
| ): |
| """ |
| A cache setup where each core has a private L1 Data and Instruction Cache, |
| and a private L2 cache. |
| """ |
| |
| @staticmethod |
| def _get_default_membus() -> SystemXBar: |
| """ |
| A method used to obtain the default memory bus of 64 bit in width for |
| the PrivateL1PrivateL2 CacheHierarchy. |
| |
| :returns: The default memory bus for the PrivateL1PrivateL2 |
| CacheHierarchy. |
| |
| :rtype: SystemXBar |
| """ |
| 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, |
| l2_size: str, |
| membus: Optional[BaseXBar] = _get_default_membus.__func__(), |
| ) -> None: |
| """ |
| :param l1d_size: The size of the L1 Data Cache (e.g., "32kB"). |
| |
| :type l1d_size: str |
| |
| :param l1i_size: The size of the L1 Instruction Cache (e.g., "32kB"). |
| |
| :type l1i_size: str |
| |
| :param l2_size: The size of the L2 Cache (e.g., "256kB"). |
| |
| :type l2_size: str |
| |
| :param membus: The memory bus. This parameter is optional parameter and |
| will default to a 64 bit width SystemXBar is not specified. |
| |
| :type membus: Optional[BaseXBar] |
| """ |
| |
| AbstractClassicCacheHierarchy.__init__(self=self) |
| AbstractTwoLevelCacheHierarchy.__init__( |
| self, |
| l1i_size=l1i_size, |
| l1i_assoc=8, |
| l1d_size=l1d_size, |
| l1d_assoc=8, |
| l2_size=l2_size, |
| l2_assoc=4, |
| ) |
| |
| self.membus = membus |
| |
| @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()) |
| ] |
| self.l2buses = [ |
| L2XBar() for i in range(board.get_processor().get_num_cores()) |
| ] |
| self.l2caches = [ |
| L2Cache(size=self._l2_size) |
| for i in range(board.get_processor().get_num_cores()) |
| ] |
| |
| 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.l2buses[i].cpu_side_ports |
| self.l1dcaches[i].mem_side = self.l2buses[i].cpu_side_ports |
| |
| self.l2buses[i].mem_side_ports = self.l2caches[i].cpu_side |
| |
| self.membus.cpu_side_ports = self.l2caches[i].mem_side |
| |
| cpu.connect_walker_ports( |
| self.membus.cpu_side_ports, self.membus.cpu_side_ports |
| ) |
| |
| 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) |