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
43 from __future__
import print_function
44 from __future__
import absolute_import
47 from m5
.objects
import *
48 from common
.Caches
import *
49 from common
import ObjectList
51 def config_cache(options
, system
):
52 if options
.external_memory_system
and (options
.caches
or options
.l2cache
):
53 print("External caches and internal caches are exclusive options.\n")
56 if options
.external_memory_system
:
57 ExternalCache
= ExternalCacheFactory(options
.external_memory_system
)
59 if options
.cpu_type
== "O3_ARM_v7a_3":
61 import cores
.arm
.O3_ARM_v7a
as core
63 print("O3_ARM_v7a_3 is unavailable. Did you compile the O3 model?")
66 dcache_class
, icache_class
, l2_cache_class
, walk_cache_class
= \
67 core
.O3_ARM_v7a_DCache
, core
.O3_ARM_v7a_ICache
, \
69 core
.O3_ARM_v7aWalkCache
70 elif options
.cpu_type
== "HPI":
72 import cores
.arm
.HPI
as core
74 print("HPI is unavailable.")
77 dcache_class
, icache_class
, l2_cache_class
, walk_cache_class
= \
78 core
.HPI_DCache
, core
.HPI_ICache
, core
.HPI_L2
, core
.HPI_WalkCache
80 dcache_class
, icache_class
, l2_cache_class
, walk_cache_class
= \
81 L1_DCache
, L1_ICache
, L2Cache
, None
83 if buildEnv
['TARGET_ISA'] in ['x86', 'riscv']:
84 walk_cache_class
= PageTableWalkerCache
86 # Set the cache line size of the system
87 system
.cache_line_size
= options
.cacheline_size
89 # If elastic trace generation is enabled, make sure the memory system is
90 # minimal so that compute delays do not include memory access latencies.
91 # Configure the compulsory L1 caches for the O3CPU, do not configure
93 if options
.l2cache
and options
.elastic_trace_en
:
94 fatal("When elastic trace is enabled, do not configure L2 caches.")
97 # Provide a clock for the L2 and the L1-to-L2 bus here as they
98 # are not connected using addTwoLevelCacheHierarchy. Use the
99 # same clock as the CPUs.
100 system
.l2
= l2_cache_class(clk_domain
=system
.cpu_clk_domain
,
101 size
=options
.l2_size
,
102 assoc
=options
.l2_assoc
)
104 system
.tol2bus
= L2XBar(clk_domain
= system
.cpu_clk_domain
)
105 system
.l2
.cpu_side
= system
.tol2bus
.master
106 system
.l2
.mem_side
= system
.membus
.slave
107 if options
.l2_hwp_type
:
108 hwpClass
= ObjectList
.hwp_list
.get(options
.l2_hwp_type
)
109 if system
.l2
.prefetcher
!= "Null":
110 print("Warning: l2-hwp-type is set (", hwpClass
, "), but",
111 "the current l2 has a default Hardware Prefetcher",
112 "of type", type(system
.l2
.prefetcher
), ", using the",
113 "specified by the flag option.")
114 system
.l2
.prefetcher
= hwpClass()
116 if options
.memchecker
:
117 system
.memchecker
= MemChecker()
119 for i
in range(options
.num_cpus
):
121 icache
= icache_class(size
=options
.l1i_size
,
122 assoc
=options
.l1i_assoc
)
123 dcache
= dcache_class(size
=options
.l1d_size
,
124 assoc
=options
.l1d_assoc
)
126 # If we have a walker cache specified, instantiate two
129 iwalkcache
= walk_cache_class()
130 dwalkcache
= walk_cache_class()
135 if options
.memchecker
:
136 dcache_mon
= MemCheckerMonitor(warn_only
=True)
139 # Do not pass the memchecker into the constructor of
140 # MemCheckerMonitor, as it would create a copy; we require
141 # exactly one MemChecker instance.
142 dcache_mon
.memchecker
= system
.memchecker
145 dcache_mon
.mem_side
= dcache
.cpu_side
147 # Let CPU connect to monitors
150 if options
.l1d_hwp_type
:
151 hwpClass
= ObjectList
.hwp_list
.get(options
.l1d_hwp_type
)
152 if dcache
.prefetcher
!= m5
.params
.NULL
:
153 print("Warning: l1d-hwp-type is set (", hwpClass
, "), but",
154 "the current l1d has a default Hardware Prefetcher",
155 "of type", type(dcache
.prefetcher
), ", using the",
156 "specified by the flag option.")
157 dcache
.prefetcher
= hwpClass()
159 if options
.l1i_hwp_type
:
160 hwpClass
= ObjectList
.hwp_list
.get(options
.l1i_hwp_type
)
161 if icache
.prefetcher
!= m5
.params
.NULL
:
162 print("Warning: l1i-hwp-type is set (", hwpClass
, "), but",
163 "the current l1i has a default Hardware Prefetcher",
164 "of type", type(icache
.prefetcher
), ", using the",
165 "specified by the flag option.")
166 icache
.prefetcher
= hwpClass()
168 # When connecting the caches, the clock is also inherited
169 # from the CPU in question
170 system
.cpu
[i
].addPrivateSplitL1Caches(icache
, dcache
,
171 iwalkcache
, dwalkcache
)
173 if options
.memchecker
:
174 # The mem_side ports of the caches haven't been connected yet.
175 # Make sure connectAllPorts connects the right objects.
176 system
.cpu
[i
].dcache
= dcache_real
177 system
.cpu
[i
].dcache_mon
= dcache_mon
179 elif options
.external_memory_system
:
180 # These port names are presented to whatever 'external' system
181 # gem5 is connecting to. Its configuration will likely depend
182 # on these names. For simplicity, we would advise configuring
183 # it to use this naming scheme; if this isn't possible, change
185 if buildEnv
['TARGET_ISA'] in ['x86', 'arm', 'riscv']:
186 system
.cpu
[i
].addPrivateSplitL1Caches(
187 ExternalCache("cpu%d.icache" % i
),
188 ExternalCache("cpu%d.dcache" % i
),
189 ExternalCache("cpu%d.itb_walker_cache" % i
),
190 ExternalCache("cpu%d.dtb_walker_cache" % i
))
192 system
.cpu
[i
].addPrivateSplitL1Caches(
193 ExternalCache("cpu%d.icache" % i
),
194 ExternalCache("cpu%d.dcache" % i
))
196 system
.cpu
[i
].createInterruptController()
198 system
.cpu
[i
].connectAllPorts(system
.tol2bus
, system
.membus
)
199 elif options
.external_memory_system
:
200 system
.cpu
[i
].connectUncachedPorts(system
.membus
)
202 system
.cpu
[i
].connectAllPorts(system
.membus
)
206 # ExternalSlave provides a "port", but when that port connects to a cache,
207 # the connecting CPU SimObject wants to refer to its "cpu_side".
208 # The 'ExternalCache' class provides this adaptation by rewriting the name,
209 # eliminating distracting changes elsewhere in the config code.
210 class ExternalCache(ExternalSlave
):
211 def __getattr__(cls
, attr
):
212 if (attr
== "cpu_side"):
214 return super(ExternalSlave
, cls
).__getattr
__(attr
)
216 def __setattr__(cls
, attr
, value
):
217 if (attr
== "cpu_side"):
219 return super(ExternalSlave
, cls
).__setattr
__(attr
, value
)
221 def ExternalCacheFactory(port_type
):
223 return ExternalCache(port_data
=name
, port_type
=port_type
,
224 addr_ranges
=[AllMemory
])