MOESI_CMP_token.py revision 8845
12SN/A# Copyright (c) 2006-2007 The Regents of The University of Michigan
21762SN/A# Copyright (c) 2009 Advanced Micro Devices, Inc.
32SN/A# All rights reserved.
42SN/A#
52SN/A# Redistribution and use in source and binary forms, with or without
62SN/A# modification, are permitted provided that the following conditions are
72SN/A# met: redistributions of source code must retain the above copyright
82SN/A# notice, this list of conditions and the following disclaimer;
92SN/A# redistributions in binary form must reproduce the above copyright
102SN/A# notice, this list of conditions and the following disclaimer in the
112SN/A# documentation and/or other materials provided with the distribution;
122SN/A# neither the name of the copyright holders nor the names of its
132SN/A# contributors may be used to endorse or promote products derived from
142SN/A# this software without specific prior written permission.
152SN/A#
162SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272SN/A#
282SN/A# Authors: Brad Beckmann
292439SN/A
30146SN/Aimport math
31146SN/Aimport m5
32146SN/Afrom m5.objects import *
33146SN/Afrom m5.defines import buildEnv
34146SN/A
35146SN/A#
361717SN/A# Note: the L1 Cache latency is only used by the sequencer on fast path hits
37146SN/A#
381717SN/Aclass L1Cache(RubyCache):
392190SN/A    latency = 2
40146SN/A
41146SN/A#
421977SN/A# Note: the L2 Cache latency is not currently used
431717SN/A#
442623SN/Aclass L2Cache(RubyCache):
451717SN/A    latency = 10
46146SN/A
471917SN/Adef define_options(parser):
482592SN/A    parser.add_option("--l1-retries", type="int", default=1,
492036SN/A                      help="Token_CMP: # of l1 retries before going persistent")
50146SN/A    parser.add_option("--timeout-latency", type="int", default=300,
51146SN/A                      help="Token_CMP: cycles until issuing again");
5256SN/A    parser.add_option("--disable-dyn-timeouts", action="store_true",
5356SN/A          help="Token_CMP: disable dyanimc timeouts, use fixed latency instead")
5456SN/A    parser.add_option("--allow-atomic-migration", action="store_true",
55695SN/A          help="allow migratory sharing for atomic only accessed blocks")
562SN/A
571858SN/Adef create_system(options, system, piobus, dma_devices, ruby_system):
5856SN/A
59146SN/A    if buildEnv['PROTOCOL'] != 'MOESI_CMP_token':
602171SN/A        panic("This script requires the MOESI_CMP_token protocol to be built.")
612170SN/A
622170SN/A    #
63146SN/A    # number of tokens that the owner passes to requests so that shared blocks can
642462SN/A    # respond to read requests
65146SN/A    #
662SN/A    n_tokens = options.num_cpus + 1
672SN/A
682449SN/A    cpu_sequencers = []
691355SN/A
702623SN/A    #
712623SN/A    # The ruby network creation expects the list of nodes in the system to be
72224SN/A    # consistent with the NetDest list.  Therefore the l1 controller nodes must be
731858SN/A    # listed before the directory nodes and directory nodes before dma nodes, etc.
742518SN/A    #
752420SN/A    l1_cntrl_nodes = []
762519SN/A    l2_cntrl_nodes = []
772520SN/A    dir_cntrl_nodes = []
782420SN/A    dma_cntrl_nodes = []
792SN/A
802190SN/A    #
812SN/A    # Must create the individual controllers before the network to ensure the
822SN/A    # controller constructors are called before the network constructor
83334SN/A    #
84140SN/A    l2_bits = int(math.log(options.num_l2caches, 2))
85334SN/A    block_size_bits = int(math.log(options.cacheline_size, 2))
862SN/A
872SN/A    cntrl_count = 0
882SN/A
892190SN/A    for i in xrange(options.num_cpus):
902SN/A        #
912SN/A        # First create the Ruby objects associated with this cpu
922623SN/A        #
932SN/A        l1i_cache = L1Cache(size = options.l1i_size,
942SN/A                            assoc = options.l1i_assoc,
952SN/A                            start_index_bit = block_size_bits)
96180SN/A        l1d_cache = L1Cache(size = options.l1d_size,
972623SN/A                            assoc = options.l1d_assoc,
98393SN/A                            start_index_bit = block_size_bits)
99393SN/A
100393SN/A        l1_cntrl = L1Cache_Controller(version = i,
101393SN/A                                      cntrl_id = cntrl_count,
102384SN/A                                      L1IcacheMemory = l1i_cache,
103384SN/A                                      L1DcacheMemory = l1d_cache,
104393SN/A                                      l2_select_num_bits = l2_bits,
1052623SN/A                                      N_tokens = n_tokens,
106393SN/A                                      retry_threshold = \
107393SN/A                                        options.l1_retries,
108393SN/A                                      fixed_timeout_latency = \
109393SN/A                                        options.timeout_latency,
110384SN/A                                      dynamic_timeout_enabled = \
111189SN/A                                        not options.disable_dyn_timeouts,
112189SN/A                                      no_mig_atomic = not \
1132623SN/A                                        options.allow_atomic_migration,
1142SN/A                                      send_evictions = (
115729SN/A                                          options.cpu_type == "detailed"),
116334SN/A                                      ruby_system = ruby_system)
1172SN/A
1182SN/A        cpu_seq = RubySequencer(version = i,
1192SN/A                                icache = l1i_cache,
1202SN/A                                dcache = l1d_cache,
1212SN/A                                physMemPort = system.physmem.port,
1222SN/A                                physmem = system.physmem,
1232SN/A                                ruby_system = ruby_system)
1242SN/A
1252SN/A        l1_cntrl.sequencer = cpu_seq
1262SN/A
1272SN/A        if piobus != None:
1282SN/A            cpu_seq.pio_port = piobus.slave
1291001SN/A
1301001SN/A        exec("system.l1_cntrl%d = l1_cntrl" % i)
1311001SN/A        #
1321001SN/A        # Add controllers and sequencers to the appropriate lists
1331001SN/A        #
1342SN/A        cpu_sequencers.append(cpu_seq)
1352SN/A        l1_cntrl_nodes.append(l1_cntrl)
1362SN/A
1372SN/A        cntrl_count += 1
1382SN/A
1392SN/A    l2_index_start = block_size_bits + l2_bits
1402SN/A
1412SN/A    for i in xrange(options.num_l2caches):
1422SN/A        #
1432SN/A        # First create the Ruby objects associated with this cpu
1442SN/A        #
1452SN/A        l2_cache = L2Cache(size = options.l2_size,
1462SN/A                           assoc = options.l2_assoc,
1472SN/A                           start_index_bit = l2_index_start)
1482SN/A
1492SN/A        l2_cntrl = L2Cache_Controller(version = i,
1502SN/A                                      cntrl_id = cntrl_count,
1512390SN/A                                      L2cacheMemory = l2_cache,
1522390SN/A                                      N_tokens = n_tokens,
1532390SN/A                                      ruby_system = ruby_system)
1542390SN/A
1552390SN/A        exec("system.l2_cntrl%d = l2_cntrl" % i)
1562390SN/A        l2_cntrl_nodes.append(l2_cntrl)
1572390SN/A
1582390SN/A        cntrl_count += 1
1592390SN/A
1602390SN/A    phys_mem_size = long(system.physmem.range.second) - \
1612390SN/A                      long(system.physmem.range.first) + 1
1622390SN/A    mem_module_size = phys_mem_size / options.num_dirs
163385SN/A
1642SN/A    for i in xrange(options.num_dirs):
1652SN/A        #
1662SN/A        # Create the Ruby objects associated with the directory controller
1672623SN/A        #
168334SN/A
169334SN/A        mem_cntrl = RubyMemoryControl(version = i)
1702623SN/A
171334SN/A        dir_size = MemorySize('0B')
172334SN/A        dir_size.value = mem_module_size
173334SN/A
1742623SN/A        dir_cntrl = Directory_Controller(version = i,
1752SN/A                                         cntrl_id = cntrl_count,
176921SN/A                                         directory = \
177224SN/A                                         RubyDirectoryMemory(version = i,
178237SN/A                                                             size = dir_size),
1792190SN/A                                         memBuffer = mem_cntrl,
1802SN/A                                         l2_select_num_bits = l2_bits,
1812SN/A                                         ruby_system = ruby_system)
1822SN/A
1832623SN/A        exec("system.dir_cntrl%d = dir_cntrl" % i)
1842SN/A        dir_cntrl_nodes.append(dir_cntrl)
185921SN/A
186224SN/A        cntrl_count += 1
1872190SN/A
1882SN/A    for i, dma_device in enumerate(dma_devices):
1892SN/A        #
1902SN/A        # Create the Ruby objects associated with the dma controller
1912SN/A        #
1922SN/A        dma_seq = DMASequencer(version = i,
1932SN/A                               physMemPort = system.physmem.port,
1942SN/A                               physmem = system.physmem,
195595SN/A                               ruby_system = ruby_system)
1962623SN/A
197595SN/A        dma_cntrl = DMA_Controller(version = i,
1982390SN/A                                   cntrl_id = cntrl_count,
1991080SN/A                                   dma_sequencer = dma_seq,
2001080SN/A                                   ruby_system = ruby_system)
2011080SN/A
2021080SN/A        exec("system.dma_cntrl%d = dma_cntrl" % i)
2031080SN/A        if dma_device.type == 'MemTest':
2041080SN/A            exec("system.dma_cntrl%d.dma_sequencer.slave = dma_device.test" % i)
2051080SN/A        else:
2061121SN/A            exec("system.dma_cntrl%d.dma_sequencer.slave = dma_device.dma" % i)
2072107SN/A        dma_cntrl_nodes.append(dma_cntrl)
2081089SN/A
2091089SN/A        cntrl_count += 1
2101080SN/A
2111080SN/A    all_cntrls = l1_cntrl_nodes + \
2121080SN/A                 l2_cntrl_nodes + \
2131080SN/A                 dir_cntrl_nodes + \
214595SN/A                 dma_cntrl_nodes
2152623SN/A
2162623SN/A    return (cpu_sequencers, dir_cntrl_nodes, all_cntrls)
217595SN/A