1 # Copyright (c) 2012-2013, 2015-2016 ARM Limited
4 # The license below extends only to copyright in the software and shall
5 # not be construed as granting a license to any other intellectual
6 # property including but not limited to intellectual property relating
7 # to a hardware implementation of the functionality of the software
8 # licensed hereunder. You may use the software subject to the license
9 # terms below provided that you ensure that this notice is replicated
10 # unmodified and in its entirety in all distributions of the software,
11 # modified or unmodified, in source code or in binary form.
13 # Copyright (c) 2010 Advanced Micro Devices, Inc.
14 # All rights reserved.
16 # Redistribution and use in source and binary forms, with or without
17 # modification, are permitted provided that the following conditions are
18 # met: redistributions of source code must retain the above copyright
19 # notice, this list of conditions and the following disclaimer;
20 # redistributions in binary form must reproduce the above copyright
21 # notice, this list of conditions and the following disclaimer in the
22 # documentation and/or other materials provided with the distribution;
23 # neither the name of the copyright holders nor the names of its
24 # contributors may be used to endorse or promote products derived from
25 # this software without specific prior written permission.
27 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 # Configure the M5 cache hierarchy config in one place
42 from __future__
import print_function
43 from __future__
import absolute_import
46 from m5
.objects
import *
48 from common
import ObjectList
50 def config_cache(options
, system
):
51 if options
.external_memory_system
and (options
.caches
or options
.l2cache
):
52 print("External caches and internal caches are exclusive options.\n")
55 if options
.external_memory_system
:
56 ExternalCache
= ExternalCacheFactory(options
.external_memory_system
)
58 if options
.cpu_type
== "O3_ARM_v7a_3":
60 import cores
.arm
.O3_ARM_v7a
as core
62 print("O3_ARM_v7a_3 is unavailable. Did you compile the O3 model?")
65 dcache_class
, icache_class
, l2_cache_class
, walk_cache_class
= \
66 core
.O3_ARM_v7a_DCache
, core
.O3_ARM_v7a_ICache
, \
68 core
.O3_ARM_v7aWalkCache
69 elif options
.cpu_type
== "HPI":
71 import cores
.arm
.HPI
as core
73 print("HPI is unavailable.")
76 dcache_class
, icache_class
, l2_cache_class
, walk_cache_class
= \
77 core
.HPI_DCache
, core
.HPI_ICache
, core
.HPI_L2
, core
.HPI_WalkCache
79 dcache_class
, icache_class
, l2_cache_class
, walk_cache_class
= \
80 L1_DCache
, L1_ICache
, L2Cache
, None
82 if buildEnv
['TARGET_ISA'] == 'x86':
83 walk_cache_class
= PageTableWalkerCache
85 # Set the cache line size of the system
86 system
.cache_line_size
= options
.cacheline_size
88 # If elastic trace generation is enabled, make sure the memory system is
89 # minimal so that compute delays do not include memory access latencies.
90 # Configure the compulsory L1 caches for the O3CPU, do not configure
92 if options
.l2cache
and options
.elastic_trace_en
:
93 fatal("When elastic trace is enabled, do not configure L2 caches.")
96 # Provide a clock for the L2 and the L1-to-L2 bus here as they
97 # are not connected using addTwoLevelCacheHierarchy. Use the
98 # same clock as the CPUs.
99 system
.l2
= l2_cache_class(clk_domain
=system
.cpu_clk_domain
,
100 size
=options
.l2_size
,
101 assoc
=options
.l2_assoc
)
103 system
.tol2bus
= L2XBar(clk_domain
= system
.cpu_clk_domain
)
104 system
.l2
.cpu_side
= system
.tol2bus
.master
105 system
.l2
.mem_side
= system
.membus
.slave
106 if options
.l2_hwp_type
:
107 hwpClass
= ObjectList
.hwp_list
.get(options
.l2_hwp_type
)
108 if system
.l2
.prefetcher
!= "Null":
109 print("Warning: l2-hwp-type is set (", hwpClass
, "), but",
110 "the current l2 has a default Hardware Prefetcher",
111 "of type", type(system
.l2
.prefetcher
), ", using the",
112 "specified by the flag option.")
113 system
.l2
.prefetcher
= hwpClass()
115 if options
.memchecker
:
116 system
.memchecker
= MemChecker()
118 for i
in range(options
.num_cpus
):
120 icache
= icache_class(size
=options
.l1i_size
,
121 assoc
=options
.l1i_assoc
)
122 dcache
= dcache_class(size
=options
.l1d_size
,
123 assoc
=options
.l1d_assoc
)
125 # If we have a walker cache specified, instantiate two
128 iwalkcache
= walk_cache_class()
129 dwalkcache
= walk_cache_class()
134 if options
.memchecker
:
135 dcache_mon
= MemCheckerMonitor(warn_only
=True)
138 # Do not pass the memchecker into the constructor of
139 # MemCheckerMonitor, as it would create a copy; we require
140 # exactly one MemChecker instance.
141 dcache_mon
.memchecker
= system
.memchecker
144 dcache_mon
.mem_side
= dcache
.cpu_side
146 # Let CPU connect to monitors
149 if options
.l1d_hwp_type
:
150 hwpClass
= ObjectList
.hwp_list
.get(options
.l1d_hwp_type
)
151 if dcache
.prefetcher
!= m5
.params
.NULL
:
152 print("Warning: l1d-hwp-type is set (", hwpClass
, "), but",
153 "the current l1d has a default Hardware Prefetcher",
154 "of type", type(dcache
.prefetcher
), ", using the",
155 "specified by the flag option.")
156 dcache
.prefetcher
= hwpClass()
158 if options
.l1i_hwp_type
:
159 hwpClass
= ObjectList
.hwp_list
.get(options
.l1i_hwp_type
)
160 if icache
.prefetcher
!= m5
.params
.NULL
:
161 print("Warning: l1i-hwp-type is set (", hwpClass
, "), but",
162 "the current l1i has a default Hardware Prefetcher",
163 "of type", type(icache
.prefetcher
), ", using the",
164 "specified by the flag option.")
165 icache
.prefetcher
= hwpClass()
167 # When connecting the caches, the clock is also inherited
168 # from the CPU in question
169 system
.cpu
[i
].addPrivateSplitL1Caches(icache
, dcache
,
170 iwalkcache
, dwalkcache
)
172 if options
.memchecker
:
173 # The mem_side ports of the caches haven't been connected yet.
174 # Make sure connectAllPorts connects the right objects.
175 system
.cpu
[i
].dcache
= dcache_real
176 system
.cpu
[i
].dcache_mon
= dcache_mon
178 elif options
.external_memory_system
:
179 # These port names are presented to whatever 'external' system
180 # gem5 is connecting to. Its configuration will likely depend
181 # on these names. For simplicity, we would advise configuring
182 # it to use this naming scheme; if this isn't possible, change
184 if buildEnv
['TARGET_ISA'] in ['x86', 'arm']:
185 system
.cpu
[i
].addPrivateSplitL1Caches(
186 ExternalCache("cpu%d.icache" % i
),
187 ExternalCache("cpu%d.dcache" % i
),
188 ExternalCache("cpu%d.itb_walker_cache" % i
),
189 ExternalCache("cpu%d.dtb_walker_cache" % i
))
191 system
.cpu
[i
].addPrivateSplitL1Caches(
192 ExternalCache("cpu%d.icache" % i
),
193 ExternalCache("cpu%d.dcache" % i
))
195 system
.cpu
[i
].createInterruptController()
197 system
.cpu
[i
].connectAllPorts(system
.tol2bus
, system
.membus
)
198 elif options
.external_memory_system
:
199 system
.cpu
[i
].connectUncachedPorts(system
.membus
)
201 system
.cpu
[i
].connectAllPorts(system
.membus
)
205 # ExternalSlave provides a "port", but when that port connects to a cache,
206 # the connecting CPU SimObject wants to refer to its "cpu_side".
207 # The 'ExternalCache' class provides this adaptation by rewriting the name,
208 # eliminating distracting changes elsewhere in the config code.
209 class ExternalCache(ExternalSlave
):
210 def __getattr__(cls
, attr
):
211 if (attr
== "cpu_side"):
213 return super(ExternalSlave
, cls
).__getattr
__(attr
)
215 def __setattr__(cls
, attr
, value
):
216 if (attr
== "cpu_side"):
218 return super(ExternalSlave
, cls
).__setattr
__(attr
, value
)
220 def ExternalCacheFactory(port_type
):
222 return ExternalCache(port_data
=name
, port_type
=port_type
,
223 addr_ranges
=[AllMemory
])