1 # Copyright (c) 2012-2013, 2015-2016 ARM Limited
2 # Copyright (c) 2020 Barkhausen Institut
5 # The license below extends only to copyright in the software and shall
6 # not be construed as granting a license to any other intellectual
7 # property including but not limited to intellectual property relating
8 # to a hardware implementation of the functionality of the software
9 # licensed hereunder. You may use the software subject to the license
10 # terms below provided that you ensure that this notice is replicated
11 # unmodified and in its entirety in all distributions of the software,
12 # modified or unmodified, in source code or in binary form.
14 # Copyright (c) 2010 Advanced Micro Devices, Inc.
15 # All rights reserved.
17 # Redistribution and use in source and binary forms, with or without
18 # modification, are permitted provided that the following conditions are
19 # met: redistributions of source code must retain the above copyright
20 # notice, this list of conditions and the following disclaimer;
21 # redistributions in binary form must reproduce the above copyright
22 # notice, this list of conditions and the following disclaimer in the
23 # documentation and/or other materials provided with the distribution;
24 # neither the name of the copyright holders nor the names of its
25 # contributors may be used to endorse or promote products derived from
26 # this software without specific prior written permission.
28 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 # Configure the M5 cache hierarchy config in one place
44 from m5
.objects
import *
45 from common
.Caches
import *
46 from common
import ObjectList
48 def _get_hwp(hwp_option
):
49 if hwp_option
== None:
52 hwpClass
= ObjectList
.hwp_list
.get(hwp_option
)
55 def _get_cache_opts(level
, options
):
58 size_attr
= '{}_size'.format(level
)
59 if hasattr(options
, size_attr
):
60 opts
['size'] = getattr(options
, size_attr
)
62 assoc_attr
= '{}_assoc'.format(level
)
63 if hasattr(options
, assoc_attr
):
64 opts
['assoc'] = getattr(options
, assoc_attr
)
66 prefetcher_attr
= '{}_hwp_type'.format(level
)
67 if hasattr(options
, prefetcher_attr
):
68 opts
['prefetcher'] = _get_hwp(getattr(options
, prefetcher_attr
))
72 def config_cache(options
, system
):
73 if options
.external_memory_system
and (options
.caches
or options
.l2cache
):
74 print("External caches and internal caches are exclusive options.\n")
77 if options
.external_memory_system
:
78 ExternalCache
= ExternalCacheFactory(options
.external_memory_system
)
80 if options
.cpu_type
== "O3_ARM_v7a_3":
82 import cores
.arm
.O3_ARM_v7a
as core
84 print("O3_ARM_v7a_3 is unavailable. Did you compile the O3 model?")
87 dcache_class
, icache_class
, l2_cache_class
, walk_cache_class
= \
88 core
.O3_ARM_v7a_DCache
, core
.O3_ARM_v7a_ICache
, \
90 core
.O3_ARM_v7aWalkCache
91 elif options
.cpu_type
== "HPI":
93 import cores
.arm
.HPI
as core
95 print("HPI is unavailable.")
98 dcache_class
, icache_class
, l2_cache_class
, walk_cache_class
= \
99 core
.HPI_DCache
, core
.HPI_ICache
, core
.HPI_L2
, core
.HPI_WalkCache
101 dcache_class
, icache_class
, l2_cache_class
, walk_cache_class
= \
102 L1_DCache
, L1_ICache
, L2Cache
, None
104 if buildEnv
['TARGET_ISA'] in ['x86', 'riscv']:
105 walk_cache_class
= PageTableWalkerCache
107 # Set the cache line size of the system
108 system
.cache_line_size
= options
.cacheline_size
110 # If elastic trace generation is enabled, make sure the memory system is
111 # minimal so that compute delays do not include memory access latencies.
112 # Configure the compulsory L1 caches for the O3CPU, do not configure
114 if options
.l2cache
and options
.elastic_trace_en
:
115 fatal("When elastic trace is enabled, do not configure L2 caches.")
118 # Provide a clock for the L2 and the L1-to-L2 bus here as they
119 # are not connected using addTwoLevelCacheHierarchy. Use the
120 # same clock as the CPUs.
121 system
.l2
= l2_cache_class(clk_domain
=system
.cpu_clk_domain
,
122 **_get_cache_opts('l2', options
))
124 system
.tol2bus
= L2XBar(clk_domain
= system
.cpu_clk_domain
)
125 system
.l2
.cpu_side
= system
.tol2bus
.master
126 system
.l2
.mem_side
= system
.membus
.slave
128 if options
.memchecker
:
129 system
.memchecker
= MemChecker()
131 for i
in range(options
.num_cpus
):
133 icache
= icache_class(**_get_cache_opts('l1i', options
))
134 dcache
= dcache_class(**_get_cache_opts('l1d', options
))
136 # If we have a walker cache specified, instantiate two
139 iwalkcache
= walk_cache_class()
140 dwalkcache
= walk_cache_class()
145 if options
.memchecker
:
146 dcache_mon
= MemCheckerMonitor(warn_only
=True)
149 # Do not pass the memchecker into the constructor of
150 # MemCheckerMonitor, as it would create a copy; we require
151 # exactly one MemChecker instance.
152 dcache_mon
.memchecker
= system
.memchecker
155 dcache_mon
.mem_side
= dcache
.cpu_side
157 # Let CPU connect to monitors
160 # When connecting the caches, the clock is also inherited
161 # from the CPU in question
162 system
.cpu
[i
].addPrivateSplitL1Caches(icache
, dcache
,
163 iwalkcache
, dwalkcache
)
165 if options
.memchecker
:
166 # The mem_side ports of the caches haven't been connected yet.
167 # Make sure connectAllPorts connects the right objects.
168 system
.cpu
[i
].dcache
= dcache_real
169 system
.cpu
[i
].dcache_mon
= dcache_mon
171 elif options
.external_memory_system
:
172 # These port names are presented to whatever 'external' system
173 # gem5 is connecting to. Its configuration will likely depend
174 # on these names. For simplicity, we would advise configuring
175 # it to use this naming scheme; if this isn't possible, change
177 if buildEnv
['TARGET_ISA'] in ['x86', 'arm', 'riscv']:
178 system
.cpu
[i
].addPrivateSplitL1Caches(
179 ExternalCache("cpu%d.icache" % i
),
180 ExternalCache("cpu%d.dcache" % i
),
181 ExternalCache("cpu%d.itb_walker_cache" % i
),
182 ExternalCache("cpu%d.dtb_walker_cache" % i
))
184 system
.cpu
[i
].addPrivateSplitL1Caches(
185 ExternalCache("cpu%d.icache" % i
),
186 ExternalCache("cpu%d.dcache" % i
))
188 system
.cpu
[i
].createInterruptController()
190 system
.cpu
[i
].connectAllPorts(system
.tol2bus
, system
.membus
)
191 elif options
.external_memory_system
:
192 system
.cpu
[i
].connectUncachedPorts(system
.membus
)
194 system
.cpu
[i
].connectAllPorts(system
.membus
)
198 # ExternalSlave provides a "port", but when that port connects to a cache,
199 # the connecting CPU SimObject wants to refer to its "cpu_side".
200 # The 'ExternalCache' class provides this adaptation by rewriting the name,
201 # eliminating distracting changes elsewhere in the config code.
202 class ExternalCache(ExternalSlave
):
203 def __getattr__(cls
, attr
):
204 if (attr
== "cpu_side"):
206 return super(ExternalSlave
, cls
).__getattr
__(attr
)
208 def __setattr__(cls
, attr
, value
):
209 if (attr
== "cpu_side"):
211 return super(ExternalSlave
, cls
).__setattr
__(attr
, value
)
213 def ExternalCacheFactory(port_type
):
215 return ExternalCache(port_data
=name
, port_type
=port_type
,
216 addr_ranges
=[AllMemory
])