MI_example.py revision 12065:e3e51756dfef
13898Ssaidi@eecs.umich.edu# Copyright (c) 2006-2007 The Regents of The University of Michigan
22934Sktlim@umich.edu# Copyright (c) 2009 Advanced Micro Devices, Inc.
32934Sktlim@umich.edu# All rights reserved.
42934Sktlim@umich.edu#
52934Sktlim@umich.edu# Redistribution and use in source and binary forms, with or without
62934Sktlim@umich.edu# modification, are permitted provided that the following conditions are
72934Sktlim@umich.edu# met: redistributions of source code must retain the above copyright
82934Sktlim@umich.edu# notice, this list of conditions and the following disclaimer;
92934Sktlim@umich.edu# redistributions in binary form must reproduce the above copyright
102934Sktlim@umich.edu# notice, this list of conditions and the following disclaimer in the
112934Sktlim@umich.edu# documentation and/or other materials provided with the distribution;
122934Sktlim@umich.edu# neither the name of the copyright holders nor the names of its
132934Sktlim@umich.edu# contributors may be used to endorse or promote products derived from
142934Sktlim@umich.edu# this software without specific prior written permission.
152934Sktlim@umich.edu#
162934Sktlim@umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172934Sktlim@umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182934Sktlim@umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192934Sktlim@umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202934Sktlim@umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212934Sktlim@umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222934Sktlim@umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232934Sktlim@umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242934Sktlim@umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252934Sktlim@umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262934Sktlim@umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272934Sktlim@umich.edu#
282934Sktlim@umich.edu# Authors: Brad Beckmann
292934Sktlim@umich.edu
302969Sktlim@umich.eduimport math
312934Sktlim@umich.eduimport m5
322995Ssaidi@eecs.umich.edufrom m5.objects import *
332934Sktlim@umich.edufrom m5.defines import buildEnv
342934Sktlim@umich.edufrom Ruby import create_topology, create_directories
352934Sktlim@umich.edufrom Ruby import send_evicts
362934Sktlim@umich.edu
372934Sktlim@umich.edu#
382934Sktlim@umich.edu# Declare caches used by the protocol
392934Sktlim@umich.edu#
402934Sktlim@umich.educlass L1Cache(RubyCache): pass
414520Ssaidi@eecs.umich.edu
424520Ssaidi@eecs.umich.edudef define_options(parser):
434982Ssaidi@eecs.umich.edu    return
444520Ssaidi@eecs.umich.edu
454520Ssaidi@eecs.umich.edudef create_system(options, full_system, system, dma_ports, ruby_system):
462934Sktlim@umich.edu
472934Sktlim@umich.edu    if buildEnv['PROTOCOL'] != 'MI_example':
483005Sstever@eecs.umich.edu        panic("This script requires the MI_example protocol to be built.")
493005Sstever@eecs.umich.edu
503304Sstever@eecs.umich.edu    cpu_sequencers = []
512995Ssaidi@eecs.umich.edu
522934Sktlim@umich.edu    #
532934Sktlim@umich.edu    # The ruby network creation expects the list of nodes in the system to be
544965Ssaidi@eecs.umich.edu    # consistent with the NetDest list.  Therefore the l1 controller nodes must be
555222Sksewell@umich.edu    # listed before the directory nodes and directory nodes before dma nodes, etc.
562934Sktlim@umich.edu    #
572934Sktlim@umich.edu    l1_cntrl_nodes = []
582934Sktlim@umich.edu    dma_cntrl_nodes = []
592934Sktlim@umich.edu
602934Sktlim@umich.edu    #
612995Ssaidi@eecs.umich.edu    # Must create the individual controllers before the network to ensure the
622934Sktlim@umich.edu    # controller constructors are called before the network constructor
632934Sktlim@umich.edu    #
642934Sktlim@umich.edu    block_size_bits = int(math.log(options.cacheline_size, 2))
652934Sktlim@umich.edu
662934Sktlim@umich.edu    for i in xrange(options.num_cpus):
672995Ssaidi@eecs.umich.edu        #
682934Sktlim@umich.edu        # First create the Ruby objects associated with this cpu
692934Sktlim@umich.edu        # Only one cache exists for this protocol, so by default use the L1D
702953Sktlim@umich.edu        # config parameters.
714094Sbinkertn@umich.edu        #
722934Sktlim@umich.edu        cache = L1Cache(size = options.l1d_size,
733449Shsul@eecs.umich.edu                        assoc = options.l1d_assoc,
742934Sktlim@umich.edu                        start_index_bit = block_size_bits)
752934Sktlim@umich.edu
762934Sktlim@umich.edu
772934Sktlim@umich.edu        # the ruby random tester reuses num_cpus to specify the
782934Sktlim@umich.edu        # number of cpu ports connected to the tester object, which
793584Ssaidi@eecs.umich.edu        # is stored in system.cpu. because there is only ever one
804486Sbinkertn@umich.edu        # tester object, num_cpus is not necessarily equal to the
814486Sbinkertn@umich.edu        # size of system.cpu; therefore if len(system.cpu) == 1
824486Sbinkertn@umich.edu        # we use system.cpu[0] to set the clk_domain, thereby ensuring
834486Sbinkertn@umich.edu        # we don't index off the end of the cpu list.
844486Sbinkertn@umich.edu        if len(system.cpu) == 1:
854486Sbinkertn@umich.edu            clk_domain = system.cpu[0].clk_domain
864486Sbinkertn@umich.edu        else:
873584Ssaidi@eecs.umich.edu            clk_domain = system.cpu[i].clk_domain
883584Ssaidi@eecs.umich.edu
893584Ssaidi@eecs.umich.edu        # Only one unified L1 cache exists. Can cache instructions and data.
903584Ssaidi@eecs.umich.edu        l1_cntrl = L1Cache_Controller(version=i, cacheMemory=cache,
913584Ssaidi@eecs.umich.edu                                      send_evictions=send_evicts(options),
923743Sgblack@eecs.umich.edu                                      transitions_per_cycle=options.ports,
933584Ssaidi@eecs.umich.edu                                      clk_domain=clk_domain,
944972Ssaidi@eecs.umich.edu                                      ruby_system=ruby_system)
953743Sgblack@eecs.umich.edu
964104Ssaidi@eecs.umich.edu        cpu_seq = RubySequencer(version=i, icache=cache, dcache=cache,
973743Sgblack@eecs.umich.edu                                clk_domain=clk_domain, ruby_system=ruby_system)
983823Ssaidi@eecs.umich.edu
993814Ssaidi@eecs.umich.edu        l1_cntrl.sequencer = cpu_seq
1003743Sgblack@eecs.umich.edu        exec("ruby_system.l1_cntrl%d = l1_cntrl" % i)
1013743Sgblack@eecs.umich.edu
1023584Ssaidi@eecs.umich.edu        # Add controllers and sequencers to the appropriate lists
1033814Ssaidi@eecs.umich.edu        cpu_sequencers.append(cpu_seq)
1043584Ssaidi@eecs.umich.edu        l1_cntrl_nodes.append(l1_cntrl)
1053745Sgblack@eecs.umich.edu
1063745Sgblack@eecs.umich.edu        # Connect the L1 controllers and the network
1073745Sgblack@eecs.umich.edu        l1_cntrl.mandatoryQueue = MessageBuffer()
1083584Ssaidi@eecs.umich.edu        l1_cntrl.requestFromCache = MessageBuffer(ordered = True)
1093898Ssaidi@eecs.umich.edu        l1_cntrl.requestFromCache.master = ruby_system.network.slave
1103898Ssaidi@eecs.umich.edu        l1_cntrl.responseFromCache = MessageBuffer(ordered = True)
1113898Ssaidi@eecs.umich.edu        l1_cntrl.responseFromCache.master = ruby_system.network.slave
1124103Ssaidi@eecs.umich.edu        l1_cntrl.forwardToCache = MessageBuffer(ordered = True)
1134103Ssaidi@eecs.umich.edu        l1_cntrl.forwardToCache.slave = ruby_system.network.master
1144103Ssaidi@eecs.umich.edu        l1_cntrl.responseToCache = MessageBuffer(ordered = True)
1153745Sgblack@eecs.umich.edu        l1_cntrl.responseToCache.slave = ruby_system.network.master
1163745Sgblack@eecs.umich.edu
1173745Sgblack@eecs.umich.edu    phys_mem_size = sum(map(lambda r: r.size(), system.mem_ranges))
1183584Ssaidi@eecs.umich.edu    assert(phys_mem_size % options.num_dirs == 0)
1193584Ssaidi@eecs.umich.edu    mem_module_size = phys_mem_size / options.num_dirs
1203584Ssaidi@eecs.umich.edu
1215222Sksewell@umich.edu    # Run each of the ruby memory controllers at a ratio of the frequency of
1225222Sksewell@umich.edu    # the ruby system.
1235222Sksewell@umich.edu    # clk_divider value is a fix to pass regression.
1245222Sksewell@umich.edu    ruby_system.memctrl_clk_domain = DerivedClockDomain(
1255222Sksewell@umich.edu                                          clk_domain=ruby_system.clk_domain,
1265222Sksewell@umich.edu                                          clk_divider=3)
1275222Sksewell@umich.edu
1285222Sksewell@umich.edu    dir_cntrl_nodes = create_directories(options, system.mem_ranges,
1295222Sksewell@umich.edu                                         ruby_system)
1305222Sksewell@umich.edu    for dir_cntrl in dir_cntrl_nodes:
1315222Sksewell@umich.edu        # Connect the directory controllers and the network
1325222Sksewell@umich.edu        dir_cntrl.requestToDir = MessageBuffer(ordered = True)
1335222Sksewell@umich.edu        dir_cntrl.requestToDir.slave = ruby_system.network.master
1345222Sksewell@umich.edu        dir_cntrl.dmaRequestToDir = MessageBuffer(ordered = True)
1355222Sksewell@umich.edu        dir_cntrl.dmaRequestToDir.slave = ruby_system.network.master
1365222Sksewell@umich.edu
1375222Sksewell@umich.edu        dir_cntrl.responseFromDir = MessageBuffer()
1385222Sksewell@umich.edu        dir_cntrl.responseFromDir.master = ruby_system.network.slave
1395222Sksewell@umich.edu        dir_cntrl.dmaResponseFromDir = MessageBuffer(ordered = True)
1405222Sksewell@umich.edu        dir_cntrl.dmaResponseFromDir.master = ruby_system.network.slave
1415222Sksewell@umich.edu        dir_cntrl.forwardFromDir = MessageBuffer()
1425222Sksewell@umich.edu        dir_cntrl.forwardFromDir.master = ruby_system.network.slave
1435222Sksewell@umich.edu        dir_cntrl.responseFromMemory = MessageBuffer()
1445222Sksewell@umich.edu
1455222Sksewell@umich.edu
1465222Sksewell@umich.edu    for i, dma_port in enumerate(dma_ports):
1475222Sksewell@umich.edu        #
1485222Sksewell@umich.edu        # Create the Ruby objects associated with the dma controller
1495222Sksewell@umich.edu        #
1505222Sksewell@umich.edu        dma_seq = DMASequencer(version = i,
1515222Sksewell@umich.edu                               ruby_system = ruby_system)
1525222Sksewell@umich.edu
1535222Sksewell@umich.edu        dma_cntrl = DMA_Controller(version = i,
1545222Sksewell@umich.edu                                   dma_sequencer = dma_seq,
1555222Sksewell@umich.edu                                   transitions_per_cycle = options.ports,
1565222Sksewell@umich.edu                                   ruby_system = ruby_system)
1575222Sksewell@umich.edu
1585133Sgblack@eecs.umich.edu        exec("ruby_system.dma_cntrl%d = dma_cntrl" % i)
1595133Sgblack@eecs.umich.edu        exec("ruby_system.dma_cntrl%d.dma_sequencer.slave = dma_port" % i)
1605133Sgblack@eecs.umich.edu        dma_cntrl_nodes.append(dma_cntrl)
1615133Sgblack@eecs.umich.edu
1625133Sgblack@eecs.umich.edu        # Connect the directory controllers and the network
1635133Sgblack@eecs.umich.edu        dma_cntrl.mandatoryQueue = MessageBuffer()
1645133Sgblack@eecs.umich.edu        dma_cntrl.requestToDir = MessageBuffer()
1655133Sgblack@eecs.umich.edu        dma_cntrl.requestToDir.master = ruby_system.network.slave
1665133Sgblack@eecs.umich.edu        dma_cntrl.responseFromDir = MessageBuffer(ordered = True)
1675133Sgblack@eecs.umich.edu        dma_cntrl.responseFromDir.slave = ruby_system.network.master
1685133Sgblack@eecs.umich.edu
1695133Sgblack@eecs.umich.edu    all_cntrls = l1_cntrl_nodes + dir_cntrl_nodes + dma_cntrl_nodes
1705133Sgblack@eecs.umich.edu
1715133Sgblack@eecs.umich.edu    # Create the io controller and the sequencer
1725133Sgblack@eecs.umich.edu    if full_system:
1735133Sgblack@eecs.umich.edu        io_seq = DMASequencer(version=len(dma_ports), ruby_system=ruby_system)
1745133Sgblack@eecs.umich.edu        ruby_system._io_port = io_seq
1755133Sgblack@eecs.umich.edu        io_controller = DMA_Controller(version = len(dma_ports),
1765133Sgblack@eecs.umich.edu                                       dma_sequencer = io_seq,
1773584Ssaidi@eecs.umich.edu                                       ruby_system = ruby_system)
1783025Ssaidi@eecs.umich.edu        ruby_system.io_controller = io_controller
1792934Sktlim@umich.edu
1802995Ssaidi@eecs.umich.edu        # Connect the dma controller to the network
1812995Ssaidi@eecs.umich.edu        io_controller.mandatoryQueue = MessageBuffer()
1824981Ssaidi@eecs.umich.edu        io_controller.requestToDir = MessageBuffer()
1834981Ssaidi@eecs.umich.edu        io_controller.requestToDir.master = ruby_system.network.slave
1844981Ssaidi@eecs.umich.edu        io_controller.responseFromDir = MessageBuffer(ordered = True)
1854981Ssaidi@eecs.umich.edu        io_controller.responseFromDir.slave = ruby_system.network.master
1863025Ssaidi@eecs.umich.edu
1873025Ssaidi@eecs.umich.edu        all_cntrls = all_cntrls + [io_controller]
1883025Ssaidi@eecs.umich.edu
1892934Sktlim@umich.edu    ruby_system.network.number_of_virtual_networks = 5
1902934Sktlim@umich.edu    topology = create_topology(all_cntrls, options)
1915253Sksewell@umich.edu    return (cpu_sequencers, dir_cntrl_nodes, topology)
1925263Sksewell@umich.edu