Пример #1
0
class BankedL3Cache(SubSystem):
    """An L3 cache that is made up of multiple L3CacheBanks
       This class creates mulitple banks that add up to a total L3 cache
       size. The current interleaving works on a cache line granularity
       with no upper-order xor bits.
       Note: We cannot use the default prefetchers with a banked cache.
    """

    SimpleOpts.add_option('--l3_size',
                          default='4MB',
                          help="L3 cache size. Default: 4MB")
    SimpleOpts.add_option('--l3_banks',
                          default=4,
                          type='int',
                          help="L3 cache banks. Default: 4")

    def __init__(self, opts):
        super(BankedL3Cache, self).__init__()

        total_size = toMemorySize(opts.l3_size)

        if total_size % opts.l3_banks:
            m5.fatal("The L3 size must be divisible by number of banks")

        bank_size = MemorySize(opts.l3_size) / opts.l3_banks
        self.banks = [
            L3CacheBank(size=bank_size) for i in range(opts.l3_banks)
        ]
        ranges = self._getInterleaveRanges(AllMemory, opts.l3_banks, 7, 20)
        for i, bank in enumerate(self.banks):
            bank.addr_ranges = ranges[i]

    def connectCPUSideBus(self, bus):
        for bank in self.banks:
            bank.connectCPUSideBus(bus)

    def connectMemSideBus(self, bus):
        for bank in self.banks:
            bank.connectMemSideBus(bus)

    def _getInterleaveRanges(self, rng, num, intlv_low_bit, xor_low_bit):
        from math import log
        bits = int(log(num, 2))
        if 2**bits != num:
            m5.fatal("Non-power of two number of memory ranges")

        intlv_bits = bits
        ranges = [
            AddrRange(start=rng.start,
                      end=rng.end,
                      intlvHighBit=intlv_low_bit + intlv_bits - 1,
                      xorHighBit=xor_low_bit + intlv_bits - 1,
                      intlvBits=intlv_bits,
                      intlvMatch=i) for i in range(num)
        ]

        return ranges
Пример #2
0
class L2Cache(PrefetchCache):
    """Simple L2 Cache with default values"""

    # Default parameters
    size = '256kB'
    assoc = 16
    tag_latency = 10
    data_latency = 10
    response_latency = 1
    mshrs = 20
    tgts_per_mshr = 12
    writeback_clean = True

    SimpleOpts.add_option('--l2_size',
                          help="L2 cache size. Default: %s" % size)

    def __init__(self, opts=None):
        super(L2Cache, self).__init__(opts)
        if not opts or not opts.l2_size:
            return
        self.size = opts.l2_size

    def connectCPUSideBus(self, bus):
        self.cpu_side = bus.master

    def connectMemSideBus(self, bus):
        self.mem_side = bus.slave
Пример #3
0
class L3Cache(Cache):
    """Simple L3 Cache bank with default values
       This assumes that the L3 is made up of multiple banks. This cannot
       be used as a standalone L3 cache.
    """

    SimpleOpts.add_option('--l3_size',
                          default='4MB',
                          help="L3 cache size. Default: 4MB")

    # Default parameters
    assoc = 32
    tag_latency = 40
    data_latency = 40
    response_latency = 10
    mshrs = 256
    tgts_per_mshr = 12
    clusivity = 'mostly_excl'

    def __init__(self, opts):
        super(L3Cache, self).__init__()
        self.size = (opts.l3_size)

    def connectCPUSideBus(self, bus):
        self.cpu_side = bus.mem_side_ports

    def connectMemSideBus(self, bus):
        self.mem_side = bus.cpu_side_ports
Пример #4
0
class PrefetchCache(Cache):

    SimpleOpts.add_option("--no_prefetchers", default=False,
                          action="store_true",
                          help="Enable prefectchers on the caches")

    def __init__(self, options):
        super(PrefetchCache, self).__init__()
        if not options or options.no_prefetchers:
            return
        self.prefetcher = StridePrefetcher()
Пример #5
0
class L1ICache(L1Cache):
    """Simple L1 instruction cache with default values"""

    # Set the default size
    size = '32kB'

    SimpleOpts.add_option('--l1i_size',
                          help="L1 instruction cache size. Default: %s" % size)

    def __init__(self, opts=None):
        super(L1ICache, self).__init__(opts)
        if not opts or not opts.l1i_size:
            return
        self.size = opts.l1i_size

    def connectCPU(self, cpu):
        """Connect this cache's port to a CPU icache port"""
        self.cpu_side = cpu.icache_port
Пример #6
0
class L1DCache(L1Cache):
    """Simple L1 data cache with default values"""

    # Set the default size
    size = '64kB'

    SimpleOpts.add_option('--l1d_size',
                          help="L1 data cache size. Default: %s" % size)

    def __init__(self, opts=None):
        super(L1DCache, self).__init__(opts)
        if not opts or not opts.l1d_size:
            return
        self.size = opts.l1d_size

    def connectCPU(self, cpu):
        """Connect this cache's port to a CPU dcache port"""
        for my_cpu in cpu:
            self.cpu_side = my_cpu.dcache_port
Пример #7
0
import sys

import m5
from m5.objects import *

sys.path.append('configs/common/')
import SimpleOpts

from system import MySystem

SimpleOpts.add_option("--script",
                      default='',
                      help="Script to execute in the simulated system")

if __name__ == "__m5_main__":
    (opts, args) = SimpleOpts.parse_args()

    system = MySystem(opts)

    system.readfile = opts.script

    root = Root(full_system=True, system=system)

    m5.instantiate()

    print("Running the simulation")
    exit_event = m5.simulate()
    print('Exiting @ tick %i because %s' %
          (m5.curTick(), exit_event.getCause()))
Пример #8
0
import sys
import time

import m5
import m5.ticks
from m5.objects import *

sys.path.append('gem5/configs/common/') # For the next line...
import SimpleOpts

from system import *

SimpleOpts.set_usage(
    "usage: %prog [options] kernel disk cpu_type mem_sys num_cpus boot_type")

SimpleOpts.add_option("--allow_listeners", default=False, action="store_true",
                      help="Listeners disabled by default")

if __name__ == "__m5_main__":
    (opts, args) = SimpleOpts.parse_args()

    if len(args) != 6:
        SimpleOpts.print_help()
        m5.fatal("Bad arguments")

    kernel, disk, cpu_type, mem_sys, num_cpus, boot_type = args
    num_cpus = int(num_cpus)

    # create the system we are going to simulate
    ruby_protocols = [ "MI_example", "MESI_Two_Level", "MOESI_CMP_directory"]
    if mem_sys == "classic":
        system = MySystem(kernel, disk, cpu_type, num_cpus, opts)
Пример #9
0
import sys

import m5
from m5.objects import *

sys.path.append('configs/common/') # For the next line...
import SimpleOpts

from system import MySystem

SimpleOpts.add_option("--script", default='',
                      help="Script to execute in the simulated system")
SimpleOpts.add_option("--n", default='1',
                      help="No of processors")

if __name__ == "__m5_main__":
    (opts, args) = SimpleOpts.parse_args()

    # create the system we are going to simulate
    system = MySystem(opts)

    # Read in the script file passed in via an option.
    # This file gets read and executed by the simulated system after boot.
    # Note: The disk image needs to be configured to do this.
    system.readfile = opts.script

    # set up the root SimObject and start the simulation
    root = Root(full_system = True, system = system)

    # instantiate all of the objects we've created above
    m5.instantiate()
Пример #10
0
import sys

import m5
from m5.objects import *

sys.path.append('configs/common/')  # For the next line...
import SimpleOpts

from system import MySystem

SimpleOpts.add_option("--script",
                      default='',
                      help="Script to execute in the simulated system")
SimpleOpts.add_option("--n", default='1', help="No of processors")

if __name__ == "__m5_main__":
    (opts, args) = SimpleOpts.parse_args()

    # create the system we are going to simulate
    system = MySystem(opts)

    # Read in the script file passed in via an option.
    # This file gets read and executed by the simulated system after boot.
    # Note: The disk image needs to be configured to do this.
    system.readfile = opts.script

    # set up the root SimObject and start the simulation
    root = Root(full_system=True, system=system)

    # instantiate all of the objects we've created above
    m5.instantiate()
# 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.
#
# Authors: Jason Lowe-Power

import SimpleOpts
import MemConfig

# Define common general options
# Note that not all optionsa are used by all systems. The actually used options
# depend on the system being used.

# Simulator options
SimpleOpts.add_option("--script",
                      default='',
                      help="Script to execute in the simulated system")
SimpleOpts.add_option("--kernel", default='', help="Linux kernel")
SimpleOpts.add_option("--disk-image", default='', help="Disk image")
SimpleOpts.add_option("--second_disk",
                      default='',
                      help="The second disk image to mount (/dev/hdb)")
SimpleOpts.add_option("--checkpoint-dir",
                      default='',
                      help="Checkpoint home directory")
SimpleOpts.add_option("--no_host_parallel", default=False, action="store_true",
                      help="Do NOT run gem5 on multiple host threads "\
                           "(kvm only)")
# FIXME: Understand what this does
SimpleOpts.add_option("--enable_tuntap",
                      action='store_true',
Пример #12
0
class SimSystem(LinuxX86System):

    SimpleOpts.add_option(
        "--no_host_parallel",
        default=False,
        action="store_true",
        help="Do NOT run gem5 on multiple host threads (kvm only)")

    SimpleOpts.add_option("--cpus",
                          default=2,
                          type="int",
                          help="Number of CPUs in the system")

    def __init__(self, opts, no_kvm=False):
        super(SimSystem, self).__init__()
        self._opts = opts
        self._no_kvm = no_kvm

        self._host_parallel = (not self._opts.no_host_parallel) & (not no_kvm)

        # Set up the clock domain and the voltage domain
        self.clk_domain = SrcClockDomain()
        self.clk_domain.clock = '3GHz'
        self.clk_domain.voltage_domain = VoltageDomain()

        # For x86, there is an I/O gap from 3GB to 4GB.
        # We can have at most 3GB of memory unless we do something special
        # to account for this I/O gap. For simplicity, this is omitted.
        mem_size = '2048MB'
        self.mem_ranges = [
            AddrRange(mem_size),
            AddrRange(0xC0000000, size=0x100000),  # For I/0
        ]

        # Create the main memory bus
        # This connects to main memory
        self.membus = SystemXBar(width=64)
        self.membus.badaddr_responder = BadAddr()
        self.membus.default = self.membus.badaddr_responder.pio

        # Set up the system port for functional access from the simulator
        self.system_port = self.membus.slave

        # This will initialize most of the x86-specific system parameters
        # This includes things like the I/O, multiprocessor support, BIOS...
        x86_mp.init_fs(self, self.membus, self._opts.cpus)
        #x86.init_fs(self, self.membus)

        # Change this path to point to the kernel you want to use
        # Kernel from http://www.m5sim.org/dist/current/x86/x86-system.tar.bz2
        self.kernel = 'linux/vmlinux'

        # Options specified on the kernel command line
        boot_options = [
            'earlyprintk=ttyS0', 'console=ttyS0', 'lpj=7999923',
            'root=/dev/hda1'
        ]
        self.boot_osflags = ' '.join(boot_options)

        # Replace these paths with the path to your disk images.
        # The first disk is the root disk. The second could be used for swap
        # or anything else.
        # Disks from http://www.m5sim.org/dist/current/x86/x86-system.tar.bz2
        self.setDiskImage('ubuntu-1604.X86.img')

        # Create the CPU for our system.
        self.createCPU()

        # Create the cache heirarchy for the system.
        self.createCacheHierarchy()

        # Create the memory controller for the sytem
        self.createMemoryControllers()

        # Set up the interrupt controllers for the system (x86 specific)
        self.setupInterrupts()

        if self._host_parallel:
            # To get the KVM CPUs to run on different host CPUs
            # Specify a different event queue for each CPU
            for i, cpu in enumerate(self.cpu):
                for obj in cpu.descendants():
                    obj.eventq_index = 0
                cpu.eventq_index = i + 1

    def getHostParallel(self):
        return self._host_parallel

    def createCPU(self):
        """ Create a CPU for the system """
        # This defaults to one simple atomic CPU. Using other CPU models
        # and using timing memory is possible as well.
        # Also, changing this to using multiple CPUs is also possible
        # Note: If you use multiple CPUs, then the BIOS config needs to be
        #       updated as well.

        if self._no_kvm:
            self.cpu = [
                AtomicSimpleCPU(cpu_id=i, switched_out=False)
                for i in range(self._opts.cpus)
            ]
            self.mem_mode = 'atomic'
        else:
            # Note KVM needs a VM and atomic_noncaching
            self.cpu = [X86KvmCPU(cpu_id=i) for i in range(self._opts.cpus)]
            self.kvm_vm = KvmVM()
            self.mem_mode = 'atomic_noncaching'

            self.atomicCpu = [
                AtomicSimpleCPU(cpu_id=i, switched_out=True)
                for i in range(self._opts.cpus)
            ]
            for cpu in self.atomicCpu:
                cpu.createThreads()

        self.timingCpu = [
            DerivO3CPU(cpu_id=i, switched_out=True)
            for i in range(self._opts.cpus)
        ]
        for cpu in self.timingCpu:
            cpu.createThreads()

        for cpu in self.cpu:
            cpu.createThreads()

    def switchCpus(self, old, new):
        assert (new[0].switchedOut())
        m5.switchCpus(self, zip(old, new))

    def setDiskImage(self, img_path):
        """ Set the disk image
            @param img_path path on the host to the image file for the disk
        """
        # Can have up to two master disk images.
        # This can be enabled with up to 4 images if using master-slave pairs
        disk0 = CowDisk(img_path)
        self.pc.south_bridge.ide.disks = [disk0]

    def createCacheHierarchy(self):
        """ Create a simple cache heirarchy with the caches"""

        # Create an L3 cache (with crossbar)
        self.l3bus = L2XBar(width=64,
                            snoop_filter=SnoopFilter(max_capacity='32MB'))

        for cpu in self.cpu:
            # Create a memory bus, a coherent crossbar, in this case
            cpu.l2bus = L2XBar()

            # Create an L1 instruction and data cache
            cpu.icache = L1ICache(self._opts)
            cpu.dcache = L1DCache(self._opts)
            cpu.mmucache = MMUCache()

            # Connect the instruction and data caches to the CPU
            cpu.icache.connectCPU(cpu)
            cpu.dcache.connectCPU(cpu)
            cpu.mmucache.connectCPU(cpu)

            # Hook the CPU ports up to the l2bus
            cpu.icache.connectBus(cpu.l2bus)
            cpu.dcache.connectBus(cpu.l2bus)
            cpu.mmucache.connectBus(cpu.l2bus)

            # Create an L2 cache and connect it to the l2bus
            cpu.l2cache = L2Cache(self._opts)
            cpu.l2cache.connectCPUSideBus(cpu.l2bus)

            # Connect the L2 cache to the L3 bus
            cpu.l2cache.connectMemSideBus(self.l3bus)

        self.l3cache = L3Cache(self._opts)
        #self.l3cache = L3Cache(self._opts)
        self.l3cache.connectCPUSideBus(self.l3bus)

        # Connect the L3 cache to the membus
        self.l3cache.connectMemSideBus(self.membus)

    def createMemoryControllers(self):
        """ Create the memory controller for the system """

        # Just create a controller for the first range, assuming the memory
        # size is < 3GB this will work. If it's > 3GB or if you want to use
        # mulitple or interleaved memory controllers then this should be
        # updated accordingly
        self.mem_cntrl = DDR3_1600_8x8(range=self.mem_ranges[0],
                                       port=self.membus.master)

    def setupInterrupts(self):
        """ Create the interrupt controller for the CPU """

        for cpu in self.cpu:
            # create the interrupt controller CPU and connect to the membus
            cpu.createInterruptController()

            # For x86 only, connect interrupts to the memory
            # Note: these are directly connected to the memory bus and
            #       not cached
            cpu.interrupts[0].pio = self.membus.master
            cpu.interrupts[0].int_master = self.membus.slave
            cpu.interrupts[0].int_slave = self.membus.master
Пример #13
0
import sys

import m5
from m5.objects import *

sys.path.append('configs/common/') # For the next line...
import SimpleOpts

from system import MySystem

SimpleOpts.add_option("--script", default='',
                      help="Script to execute in the simulated system")

if __name__ == "__m5_main__":
    (opts, args) = SimpleOpts.parse_args()

    # create the system we are going to simulate
    system = MySystem(opts)

    # Read in the script file passed in via an option.
    # This file gets read and executed by the simulated system after boot.
    # Note: The disk image needs to be configured to do this.
    system.readfile = opts.script

    # set up the root SimObject and start the simulation
    root = Root(full_system = True, system = system)

    # instantiate all of the objects we've created above
    m5.instantiate()

    # Keep running until we are done.
Пример #14
0
"""

import sys
import time

import m5
import m5.ticks
from m5.objects import *

sys.path.append('configs/common/')  # For the next line...
import SimpleOpts

from system import MySystem

SimpleOpts.add_option("--script",
                      default='',
                      help="Script to execute in the simulated system")
SimpleOpts.add_option("--kernel", default='', help="Linux kernel")
SimpleOpts.add_option("--disk-image", default='', help="Disk image")

if __name__ == "__m5_main__":
    (opts, args) = SimpleOpts.parse_args()

    # create the system we are going to simulate
    system = MySystem(opts)

    # For workitems to work correctly
    # This will cause the simulator to exit simulation when the first work
    # item is reached and when the first work item is finished.
    system.work_begin_exit_count = 1
    system.work_end_exit_count = 1