112610Sjason@lowepower.com# -*- coding: utf-8 -*-
212610Sjason@lowepower.com# Copyright (c) 2017 Jason Power
312610Sjason@lowepower.com# All rights reserved.
412610Sjason@lowepower.com#
512610Sjason@lowepower.com# Redistribution and use in source and binary forms, with or without
612610Sjason@lowepower.com# modification, are permitted provided that the following conditions are
712610Sjason@lowepower.com# met: redistributions of source code must retain the above copyright
812610Sjason@lowepower.com# notice, this list of conditions and the following disclaimer;
912610Sjason@lowepower.com# redistributions in binary form must reproduce the above copyright
1012610Sjason@lowepower.com# notice, this list of conditions and the following disclaimer in the
1112610Sjason@lowepower.com# documentation and/or other materials provided with the distribution;
1212610Sjason@lowepower.com# neither the name of the copyright holders nor the names of its
1312610Sjason@lowepower.com# contributors may be used to endorse or promote products derived from
1412610Sjason@lowepower.com# this software without specific prior written permission.
1512610Sjason@lowepower.com#
1612610Sjason@lowepower.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712610Sjason@lowepower.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812610Sjason@lowepower.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912610Sjason@lowepower.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012610Sjason@lowepower.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112610Sjason@lowepower.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212610Sjason@lowepower.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312610Sjason@lowepower.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412610Sjason@lowepower.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512610Sjason@lowepower.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612610Sjason@lowepower.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712610Sjason@lowepower.com#
2812610Sjason@lowepower.com# Authors: Jason Power
2912610Sjason@lowepower.com
3012610Sjason@lowepower.com""" This file creates a set of Ruby caches, the Ruby network, and a simple
3112610Sjason@lowepower.compoint-to-point topology for the RubyRandomTester to use.
3212610Sjason@lowepower.comSee Part 3 in the Learning gem5 book: learning.gem5.org/book/part3
3312610Sjason@lowepower.com
3412610Sjason@lowepower.comIMPORTANT: If you modify this file, it's likely that the Learning gem5 book
3512610Sjason@lowepower.com           also needs to be updated. For now, email Jason <jason@lowepower.com>
3612610Sjason@lowepower.com
3712610Sjason@lowepower.com"""
3812610Sjason@lowepower.com
3913774Sandreas.sandberg@arm.comfrom __future__ import print_function
4013774Sandreas.sandberg@arm.comfrom __future__ import absolute_import
4113774Sandreas.sandberg@arm.com
4212610Sjason@lowepower.comfrom m5.defines import buildEnv
4312610Sjason@lowepower.comfrom m5.util import fatal
4412610Sjason@lowepower.com
4512610Sjason@lowepower.comfrom m5.objects import *
4612610Sjason@lowepower.com
4713840Sjason@lowepower.comfrom msi_caches import L1Cache, DirController, MyNetwork
4812610Sjason@lowepower.com
4912610Sjason@lowepower.comclass TestCacheSystem(RubySystem):
5012610Sjason@lowepower.com
5112610Sjason@lowepower.com    def __init__(self):
5212610Sjason@lowepower.com        if buildEnv['PROTOCOL'] != 'MSI':
5312610Sjason@lowepower.com            fatal("This system assumes MSI from learning gem5!")
5412610Sjason@lowepower.com
5512610Sjason@lowepower.com        super(TestCacheSystem, self).__init__()
5612610Sjason@lowepower.com
5712610Sjason@lowepower.com    def setup(self, system, tester, mem_ctrls):
5812610Sjason@lowepower.com        """Set up the Ruby cache subsystem. Note: This can't be done in the
5912610Sjason@lowepower.com           constructor because many of these items require a pointer to the
6012610Sjason@lowepower.com           ruby system (self). This causes infinite recursion in initialize()
6112610Sjason@lowepower.com           if we do this in the __init__.
6212610Sjason@lowepower.com           Setting up for running the RubyRandomTester is a little different
6312610Sjason@lowepower.com           than when we're using CPUs.
6412610Sjason@lowepower.com        """
6512610Sjason@lowepower.com        num_testers = tester.num_cpus
6612610Sjason@lowepower.com
6712610Sjason@lowepower.com        # Ruby's global network.
6812610Sjason@lowepower.com        self.network = MyNetwork(self)
6912610Sjason@lowepower.com
7012610Sjason@lowepower.com        # MSI uses 3 virtual networks
7112610Sjason@lowepower.com        self.number_of_virtual_networks = 3
7212610Sjason@lowepower.com        self.network.number_of_virtual_networks = 3
7312610Sjason@lowepower.com
7412610Sjason@lowepower.com        self.controllers = \
7512610Sjason@lowepower.com            [L1Cache(system, self, self) for i in range(num_testers)] + \
7612610Sjason@lowepower.com            [DirController(self, system.mem_ranges, mem_ctrls)]
7712610Sjason@lowepower.com
7812610Sjason@lowepower.com        self.sequencers = [RubySequencer(version = i,
7912610Sjason@lowepower.com                              # I/D cache is combined and grab from ctrl
8012610Sjason@lowepower.com                              icache = self.controllers[i].cacheMemory,
8112610Sjason@lowepower.com                              dcache = self.controllers[i].cacheMemory,
8212610Sjason@lowepower.com                              clk_domain = self.clk_domain,
8312610Sjason@lowepower.com                              ) for i in range(num_testers)]
8412610Sjason@lowepower.com
8512610Sjason@lowepower.com        for i,c in enumerate(self.controllers[0:len(self.sequencers)]):
8612610Sjason@lowepower.com            c.sequencer = self.sequencers[i]
8712610Sjason@lowepower.com
8812610Sjason@lowepower.com        self.num_of_sequencers = len(self.sequencers)
8912610Sjason@lowepower.com
9012610Sjason@lowepower.com        # Create the network and connect the controllers.
9112610Sjason@lowepower.com        # NOTE: This is quite different if using Garnet!
9212610Sjason@lowepower.com        self.network.connectControllers(self.controllers)
9312610Sjason@lowepower.com        self.network.setup_buffers()
9412610Sjason@lowepower.com
9512610Sjason@lowepower.com        # Set up a proxy port for the system_port. Used for load binaries and
9612610Sjason@lowepower.com        # other functional-only things.
9712610Sjason@lowepower.com        self.sys_port_proxy = RubyPortProxy()
9812610Sjason@lowepower.com        system.system_port = self.sys_port_proxy.slave
9912610Sjason@lowepower.com
10012610Sjason@lowepower.com        # Connect up the sequencers to the random tester
10112610Sjason@lowepower.com        for seq in self.sequencers:
10212610Sjason@lowepower.com            if seq.support_data_reqs and seq.support_inst_reqs:
10312610Sjason@lowepower.com                tester.cpuInstDataPort = seq.slave
10412610Sjason@lowepower.com            elif seq.support_data_reqs:
10512610Sjason@lowepower.com                tester.cpuDataPort = seq.slave
10612610Sjason@lowepower.com            elif seq.support_inst_reqs:
10712610Sjason@lowepower.com                tester.cpuInstDataPort = seq.slave
10812610Sjason@lowepower.com
10912610Sjason@lowepower.com            # Do not automatically retry stalled Ruby requests
11012610Sjason@lowepower.com            seq.no_retry_on_stall = True
11112610Sjason@lowepower.com
11212610Sjason@lowepower.com            # Tell each sequencer this is the ruby tester so that it
11312610Sjason@lowepower.com            # copies the subblock back to the checker
11412610Sjason@lowepower.com            seq.using_ruby_tester = True
115