MI_example.py revision 10006:8fa94dcfd545
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.
272665Ssaidi@eecs.umich.edu#
282665Ssaidi@eecs.umich.edu# Authors: Brad Beckmann
292665Ssaidi@eecs.umich.edu
302SN/Aimport math
312SN/Aimport m5
322SN/Afrom m5.objects import *
332SN/Afrom m5.defines import buildEnv
342SN/Afrom Ruby import create_topology
355882Snate@binkert.org
3656SN/A#
379356Snilay@cs.wisc.edu# Note: the cache latency is only used by the sequencer on fast path hits
389983Sstever@gmail.com#
3956SN/Aclass Cache(RubyCache):
408278SAli.Saidi@ARM.com    latency = 3
4111157SDylan.Johnson@ARM.com
4211157SDylan.Johnson@ARM.comdef define_options(parser):
432SN/A    return
442SN/A
452SN/Adef create_system(options, system, piobus, dma_ports, ruby_system):
462SN/A
472SN/A    if buildEnv['PROTOCOL'] != 'MI_example':
482SN/A        panic("This script requires the MI_example protocol to be built.")
492SN/A
509983Sstever@gmail.com    cpu_sequencers = []
512SN/A
529983Sstever@gmail.com    #
535543Ssaidi@eecs.umich.edu    # The ruby network creation expects the list of nodes in the system to be
545336Shines@cs.fsu.edu    # consistent with the NetDest list.  Therefore the l1 controller nodes must be
552SN/A    # listed before the directory nodes and directory nodes before dma nodes, etc.
562SN/A    #
572SN/A    l1_cntrl_nodes = []
582SN/A    dir_cntrl_nodes = []
592SN/A    dma_cntrl_nodes = []
609983Sstever@gmail.com
619983Sstever@gmail.com    #
622SN/A    # Must create the individual controllers before the network to ensure the
632SN/A    # controller constructors are called before the network constructor
642SN/A    #
652SN/A    block_size_bits = int(math.log(options.cacheline_size, 2))
662SN/A
672SN/A    for i in xrange(options.num_cpus):
682SN/A        #
692SN/A        # First create the Ruby objects associated with this cpu
702SN/A        # Only one cache exists for this protocol, so by default use the L1D
718231Snate@binkert.org        # config parameters.
722SN/A        #
732SN/A        cache = Cache(size = options.l1d_size,
742SN/A                      assoc = options.l1d_assoc,
752SN/A                      start_index_bit = block_size_bits)
765336Shines@cs.fsu.edu
772SN/A        #
788231Snate@binkert.org        # Only one unified L1 cache exists.  Can cache instructions and data.
792SN/A        #
802SN/A        l1_cntrl = L1Cache_Controller(version = i,
812SN/A                                      cacheMemory = cache,
822SN/A                                      send_evictions = (
832SN/A                                          options.cpu_type == "detailed"),
842SN/A                                      transitions_per_cycle = options.ports,
853645Sbinkertn@umich.edu                                      ruby_system = ruby_system)
869960Sandreas.hansson@arm.com
872SN/A        cpu_seq = RubySequencer(version = i,
889983Sstever@gmail.com                                icache = cache,
895606Snate@binkert.org                                dcache = cache,
902SN/A                                ruby_system = ruby_system)
912SN/A
9211157SDylan.Johnson@ARM.com        l1_cntrl.sequencer = cpu_seq
9311164SDylan.Johnson@ARM.com
9411164SDylan.Johnson@ARM.com        if piobus != None:
9511164SDylan.Johnson@ARM.com            cpu_seq.pio_port = piobus.slave
9611164SDylan.Johnson@ARM.com
9711164SDylan.Johnson@ARM.com        exec("ruby_system.l1_cntrl%d = l1_cntrl" % i)
9811164SDylan.Johnson@ARM.com        #
9911157SDylan.Johnson@ARM.com        # Add controllers and sequencers to the appropriate lists
10011157SDylan.Johnson@ARM.com        #
10111157SDylan.Johnson@ARM.com        cpu_sequencers.append(cpu_seq)
10211157SDylan.Johnson@ARM.com        l1_cntrl_nodes.append(l1_cntrl)
10311157SDylan.Johnson@ARM.com
10411157SDylan.Johnson@ARM.com    phys_mem_size = sum(map(lambda r: r.size(), system.mem_ranges))
10511157SDylan.Johnson@ARM.com    assert(phys_mem_size % options.num_dirs == 0)
1068278SAli.Saidi@ARM.com    mem_module_size = phys_mem_size / options.num_dirs
1078278SAli.Saidi@ARM.com
1088278SAli.Saidi@ARM.com    # Run each of the ruby memory controllers at a ratio of the frequency of
1098278SAli.Saidi@ARM.com    # the ruby system.
1108278SAli.Saidi@ARM.com    # clk_divider value is a fix to pass regression.
1118278SAli.Saidi@ARM.com    ruby_system.memctrl_clk_domain = DerivedClockDomain(
1128278SAli.Saidi@ARM.com                                          clk_domain=ruby_system.clk_domain,
1138278SAli.Saidi@ARM.com                                          clk_divider=3)
1148278SAli.Saidi@ARM.com
1158278SAli.Saidi@ARM.com    for i in xrange(options.num_dirs):
1168278SAli.Saidi@ARM.com        #
1173645Sbinkertn@umich.edu        # Create the Ruby objects associated with the directory controller
1183645Sbinkertn@umich.edu        #
1192SN/A
1209983Sstever@gmail.com        mem_cntrl = RubyMemoryControl(
1219983Sstever@gmail.com                              clk_domain = ruby_system.memctrl_clk_domain,
1229983Sstever@gmail.com                              version = i,
1232SN/A                              ruby_system = ruby_system)
1242SN/A
1255512SMichael.Adler@intel.com        dir_size = MemorySize('0B')
1265512SMichael.Adler@intel.com        dir_size.value = mem_module_size
1275512SMichael.Adler@intel.com
1285512SMichael.Adler@intel.com        dir_cntrl = Directory_Controller(version = i,
1295512SMichael.Adler@intel.com                                         directory = \
1305512SMichael.Adler@intel.com                                         RubyDirectoryMemory( \
1315512SMichael.Adler@intel.com                                                    version = i,
1325512SMichael.Adler@intel.com                                                    size = dir_size,
1335512SMichael.Adler@intel.com                                                    use_map = options.use_map,
1345512SMichael.Adler@intel.com                                                    map_levels = \
1355512SMichael.Adler@intel.com                                                      options.map_levels),
1365512SMichael.Adler@intel.com                                         memBuffer = mem_cntrl,
1375512SMichael.Adler@intel.com                                         transitions_per_cycle = options.ports,
1385512SMichael.Adler@intel.com                                         ruby_system = ruby_system)
1395512SMichael.Adler@intel.com
1405512SMichael.Adler@intel.com        exec("ruby_system.dir_cntrl%d = dir_cntrl" % i)
141        dir_cntrl_nodes.append(dir_cntrl)
142
143    for i, dma_port in enumerate(dma_ports):
144        #
145        # Create the Ruby objects associated with the dma controller
146        #
147        dma_seq = DMASequencer(version = i,
148                               ruby_system = ruby_system)
149
150        dma_cntrl = DMA_Controller(version = i,
151                                   dma_sequencer = dma_seq,
152                                   transitions_per_cycle = options.ports,
153                                   ruby_system = ruby_system)
154
155        exec("ruby_system.dma_cntrl%d = dma_cntrl" % i)
156        exec("ruby_system.dma_cntrl%d.dma_sequencer.slave = dma_port" % i)
157        dma_cntrl_nodes.append(dma_cntrl)
158
159    all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes + dma_cntrl_nodes
160
161    topology = create_topology(all_cntrls, options)
162
163    return (cpu_sequencers, dir_cntrl_nodes, topology)
164