113971Stiago.muck@arm.com# Copyright (c) 2019 ARM Limited 213971Stiago.muck@arm.com# All rights reserved. 313971Stiago.muck@arm.com# 413971Stiago.muck@arm.com# The license below extends only to copyright in the software and shall 513971Stiago.muck@arm.com# not be construed as granting a license to any other intellectual 613971Stiago.muck@arm.com# property including but not limited to intellectual property relating 713971Stiago.muck@arm.com# to a hardware implementation of the functionality of the software 813971Stiago.muck@arm.com# licensed hereunder. You may use the software subject to the license 913971Stiago.muck@arm.com# terms below provided that you ensure that this notice is replicated 1013971Stiago.muck@arm.com# unmodified and in its entirety in all distributions of the software, 1113971Stiago.muck@arm.com# modified or unmodified, in source code or in binary form. 1213971Stiago.muck@arm.com# 136911SBrad.Beckmann@amd.com# Copyright (c) 2006-2007 The Regents of The University of Michigan 146911SBrad.Beckmann@amd.com# Copyright (c) 2009 Advanced Micro Devices, Inc. 156911SBrad.Beckmann@amd.com# All rights reserved. 166911SBrad.Beckmann@amd.com# 176911SBrad.Beckmann@amd.com# Redistribution and use in source and binary forms, with or without 186911SBrad.Beckmann@amd.com# modification, are permitted provided that the following conditions are 196911SBrad.Beckmann@amd.com# met: redistributions of source code must retain the above copyright 206911SBrad.Beckmann@amd.com# notice, this list of conditions and the following disclaimer; 216911SBrad.Beckmann@amd.com# redistributions in binary form must reproduce the above copyright 226911SBrad.Beckmann@amd.com# notice, this list of conditions and the following disclaimer in the 236911SBrad.Beckmann@amd.com# documentation and/or other materials provided with the distribution; 246911SBrad.Beckmann@amd.com# neither the name of the copyright holders nor the names of its 256911SBrad.Beckmann@amd.com# contributors may be used to endorse or promote products derived from 266911SBrad.Beckmann@amd.com# this software without specific prior written permission. 276911SBrad.Beckmann@amd.com# 286911SBrad.Beckmann@amd.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 296911SBrad.Beckmann@amd.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 306911SBrad.Beckmann@amd.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 316911SBrad.Beckmann@amd.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 326911SBrad.Beckmann@amd.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 336911SBrad.Beckmann@amd.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 346911SBrad.Beckmann@amd.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 356911SBrad.Beckmann@amd.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 366911SBrad.Beckmann@amd.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 376911SBrad.Beckmann@amd.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 386911SBrad.Beckmann@amd.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 396911SBrad.Beckmann@amd.com# 406911SBrad.Beckmann@amd.com# Authors: Brad Beckmann 416911SBrad.Beckmann@amd.com 426911SBrad.Beckmann@amd.comimport math 436911SBrad.Beckmann@amd.comimport m5 446911SBrad.Beckmann@amd.comfrom m5.objects import * 456911SBrad.Beckmann@amd.comfrom m5.defines import buildEnv 4612065Snikos.nikoleris@arm.comfrom Ruby import create_topology, create_directories 4710529Smorr@cs.wisc.edufrom Ruby import send_evicts 486911SBrad.Beckmann@amd.com 496911SBrad.Beckmann@amd.com# 5011019Sjthestness@gmail.com# Declare caches used by the protocol 516911SBrad.Beckmann@amd.com# 5213975Stiago.muck@arm.comclass L1Cache(RubyCache): 5313975Stiago.muck@arm.com dataAccessLatency = 1 5413975Stiago.muck@arm.com tagAccessLatency = 1 5513975Stiago.muck@arm.com 5613975Stiago.muck@arm.comclass L2Cache(RubyCache): 5713975Stiago.muck@arm.com dataAccessLatency = 20 5813975Stiago.muck@arm.com tagAccessLatency = 20 596911SBrad.Beckmann@amd.com 607538SBrad.Beckmann@amd.comdef define_options(parser): 617538SBrad.Beckmann@amd.com return 627538SBrad.Beckmann@amd.com 6312598Snikos.nikoleris@arm.comdef create_system(options, full_system, system, dma_ports, bootmem, 6412598Snikos.nikoleris@arm.com ruby_system): 658436SBrad.Beckmann@amd.com 666911SBrad.Beckmann@amd.com if buildEnv['PROTOCOL'] != 'MOESI_CMP_directory': 676911SBrad.Beckmann@amd.com panic("This script requires the MOESI_CMP_directory protocol to be built.") 686911SBrad.Beckmann@amd.com 696911SBrad.Beckmann@amd.com cpu_sequencers = [] 7010917Sbrandon.potter@amd.com 716911SBrad.Beckmann@amd.com # 726911SBrad.Beckmann@amd.com # The ruby network creation expects the list of nodes in the system to be 736911SBrad.Beckmann@amd.com # consistent with the NetDest list. Therefore the l1 controller nodes must be 746911SBrad.Beckmann@amd.com # listed before the directory nodes and directory nodes before dma nodes, etc. 756911SBrad.Beckmann@amd.com # 766911SBrad.Beckmann@amd.com l1_cntrl_nodes = [] 776911SBrad.Beckmann@amd.com l2_cntrl_nodes = [] 786911SBrad.Beckmann@amd.com dma_cntrl_nodes = [] 796911SBrad.Beckmann@amd.com 806911SBrad.Beckmann@amd.com # 816911SBrad.Beckmann@amd.com # Must create the individual controllers before the network to ensure the 826911SBrad.Beckmann@amd.com # controller constructors are called before the network constructor 836911SBrad.Beckmann@amd.com # 848180SBrad.Beckmann@amd.com block_size_bits = int(math.log(options.cacheline_size, 2)) 858257SBrad.Beckmann@amd.com 8613731Sandreas.sandberg@arm.com for i in range(options.num_cpus): 876911SBrad.Beckmann@amd.com # 886911SBrad.Beckmann@amd.com # First create the Ruby objects associated with this cpu 896911SBrad.Beckmann@amd.com # 906911SBrad.Beckmann@amd.com l1i_cache = L1Cache(size = options.l1i_size, 918180SBrad.Beckmann@amd.com assoc = options.l1i_assoc, 929319Smalek.musleh@gmail.com start_index_bit = block_size_bits, 939319Smalek.musleh@gmail.com is_icache = True) 946911SBrad.Beckmann@amd.com l1d_cache = L1Cache(size = options.l1d_size, 958180SBrad.Beckmann@amd.com assoc = options.l1d_assoc, 969319Smalek.musleh@gmail.com start_index_bit = block_size_bits, 979319Smalek.musleh@gmail.com is_icache = False) 986911SBrad.Beckmann@amd.com 9911266SBrad.Beckmann@amd.com # the ruby random tester reuses num_cpus to specify the 10011266SBrad.Beckmann@amd.com # number of cpu ports connected to the tester object, which 10111266SBrad.Beckmann@amd.com # is stored in system.cpu. because there is only ever one 10211266SBrad.Beckmann@amd.com # tester object, num_cpus is not necessarily equal to the 10311266SBrad.Beckmann@amd.com # size of system.cpu; therefore if len(system.cpu) == 1 10411266SBrad.Beckmann@amd.com # we use system.cpu[0] to set the clk_domain, thereby ensuring 10511266SBrad.Beckmann@amd.com # we don't index off the end of the cpu list. 10611266SBrad.Beckmann@amd.com if len(system.cpu) == 1: 10711266SBrad.Beckmann@amd.com clk_domain = system.cpu[0].clk_domain 10811266SBrad.Beckmann@amd.com else: 10911266SBrad.Beckmann@amd.com clk_domain = system.cpu[i].clk_domain 1108322Ssteve.reinhardt@amd.com 11111266SBrad.Beckmann@amd.com l1_cntrl = L1Cache_Controller(version=i, L1Icache=l1i_cache, 11211266SBrad.Beckmann@amd.com L1Dcache=l1d_cache, 11311266SBrad.Beckmann@amd.com send_evictions=send_evicts(options), 11411266SBrad.Beckmann@amd.com transitions_per_cycle=options.ports, 11511266SBrad.Beckmann@amd.com clk_domain=clk_domain, 11611266SBrad.Beckmann@amd.com ruby_system=ruby_system) 11711266SBrad.Beckmann@amd.com 11811266SBrad.Beckmann@amd.com cpu_seq = RubySequencer(version=i, icache=l1i_cache, 11911266SBrad.Beckmann@amd.com dcache=l1d_cache, clk_domain=clk_domain, 12011266SBrad.Beckmann@amd.com ruby_system=ruby_system) 1216911SBrad.Beckmann@amd.com 1228322Ssteve.reinhardt@amd.com l1_cntrl.sequencer = cpu_seq 12310116Snilay@cs.wisc.edu exec("ruby_system.l1_cntrl%d = l1_cntrl" % i) 1248322Ssteve.reinhardt@amd.com 1256911SBrad.Beckmann@amd.com # Add controllers and sequencers to the appropriate lists 1266911SBrad.Beckmann@amd.com cpu_sequencers.append(cpu_seq) 1276911SBrad.Beckmann@amd.com l1_cntrl_nodes.append(l1_cntrl) 1286911SBrad.Beckmann@amd.com 12910311Snilay@cs.wisc.edu # Connect the L1 controllers and the network 13011022Sjthestness@gmail.com l1_cntrl.mandatoryQueue = MessageBuffer() 13111022Sjthestness@gmail.com l1_cntrl.requestFromL1Cache = MessageBuffer() 13211022Sjthestness@gmail.com l1_cntrl.requestFromL1Cache.master = ruby_system.network.slave 13311022Sjthestness@gmail.com l1_cntrl.responseFromL1Cache = MessageBuffer() 13411022Sjthestness@gmail.com l1_cntrl.responseFromL1Cache.master = ruby_system.network.slave 13511022Sjthestness@gmail.com l1_cntrl.requestToL1Cache = MessageBuffer() 13611022Sjthestness@gmail.com l1_cntrl.requestToL1Cache.slave = ruby_system.network.master 13711022Sjthestness@gmail.com l1_cntrl.responseToL1Cache = MessageBuffer() 13811022Sjthestness@gmail.com l1_cntrl.responseToL1Cache.slave = ruby_system.network.master 13911022Sjthestness@gmail.com l1_cntrl.triggerQueue = MessageBuffer(ordered = True) 14010311Snilay@cs.wisc.edu 14110311Snilay@cs.wisc.edu 14213971Stiago.muck@arm.com # Create the L2s interleaved addr ranges 14313971Stiago.muck@arm.com l2_addr_ranges = [] 14413971Stiago.muck@arm.com l2_bits = int(math.log(options.num_l2caches, 2)) 14513971Stiago.muck@arm.com numa_bit = block_size_bits + l2_bits - 1 14613971Stiago.muck@arm.com sysranges = [] + system.mem_ranges 14713971Stiago.muck@arm.com if bootmem: sysranges.append(bootmem.range) 14813971Stiago.muck@arm.com for i in range(options.num_l2caches): 14913971Stiago.muck@arm.com ranges = [] 15013971Stiago.muck@arm.com for r in sysranges: 15113971Stiago.muck@arm.com addr_range = AddrRange(r.start, size = r.size(), 15213971Stiago.muck@arm.com intlvHighBit = numa_bit, 15313971Stiago.muck@arm.com intlvBits = l2_bits, 15413971Stiago.muck@arm.com intlvMatch = i) 15513971Stiago.muck@arm.com ranges.append(addr_range) 15613971Stiago.muck@arm.com l2_addr_ranges.append(ranges) 1578180SBrad.Beckmann@amd.com 15813731Sandreas.sandberg@arm.com for i in range(options.num_l2caches): 1596911SBrad.Beckmann@amd.com # 1606911SBrad.Beckmann@amd.com # First create the Ruby objects associated with this cpu 1616911SBrad.Beckmann@amd.com # 1626911SBrad.Beckmann@amd.com l2_cache = L2Cache(size = options.l2_size, 1638180SBrad.Beckmann@amd.com assoc = options.l2_assoc, 16413971Stiago.muck@arm.com start_index_bit = block_size_bits + l2_bits) 1656911SBrad.Beckmann@amd.com 1666911SBrad.Beckmann@amd.com l2_cntrl = L2Cache_Controller(version = i, 1679694Snilay@cs.wisc.edu L2cache = l2_cache, 1689841Snilay@cs.wisc.edu transitions_per_cycle = options.ports, 16913971Stiago.muck@arm.com ruby_system = ruby_system, 17013971Stiago.muck@arm.com addr_ranges = l2_addr_ranges[i]) 17110917Sbrandon.potter@amd.com 1729468Smalek.musleh@gmail.com exec("ruby_system.l2_cntrl%d = l2_cntrl" % i) 1736911SBrad.Beckmann@amd.com l2_cntrl_nodes.append(l2_cntrl) 1748257SBrad.Beckmann@amd.com 17510311Snilay@cs.wisc.edu # Connect the L2 controllers and the network 17611022Sjthestness@gmail.com l2_cntrl.GlobalRequestFromL2Cache = MessageBuffer() 17711022Sjthestness@gmail.com l2_cntrl.GlobalRequestFromL2Cache.master = ruby_system.network.slave 17811022Sjthestness@gmail.com l2_cntrl.L1RequestFromL2Cache = MessageBuffer() 17911022Sjthestness@gmail.com l2_cntrl.L1RequestFromL2Cache.master = ruby_system.network.slave 18011022Sjthestness@gmail.com l2_cntrl.responseFromL2Cache = MessageBuffer() 18111022Sjthestness@gmail.com l2_cntrl.responseFromL2Cache.master = ruby_system.network.slave 18210311Snilay@cs.wisc.edu 18311022Sjthestness@gmail.com l2_cntrl.GlobalRequestToL2Cache = MessageBuffer() 18411022Sjthestness@gmail.com l2_cntrl.GlobalRequestToL2Cache.slave = ruby_system.network.master 18511022Sjthestness@gmail.com l2_cntrl.L1RequestToL2Cache = MessageBuffer() 18611022Sjthestness@gmail.com l2_cntrl.L1RequestToL2Cache.slave = ruby_system.network.master 18711022Sjthestness@gmail.com l2_cntrl.responseToL2Cache = MessageBuffer() 18811022Sjthestness@gmail.com l2_cntrl.responseToL2Cache.slave = ruby_system.network.master 18911022Sjthestness@gmail.com l2_cntrl.triggerQueue = MessageBuffer(ordered = True) 19010311Snilay@cs.wisc.edu 1919793Sakash.bagdia@arm.com # Run each of the ruby memory controllers at a ratio of the frequency of 1929793Sakash.bagdia@arm.com # the ruby system. 1939793Sakash.bagdia@arm.com # clk_divider value is a fix to pass regression. 1949793Sakash.bagdia@arm.com ruby_system.memctrl_clk_domain = DerivedClockDomain( 1959793Sakash.bagdia@arm.com clk_domain=ruby_system.clk_domain, 1969793Sakash.bagdia@arm.com clk_divider=3) 1979793Sakash.bagdia@arm.com 1986911SBrad.Beckmann@amd.com 19912598Snikos.nikoleris@arm.com mem_dir_cntrl_nodes, rom_dir_cntrl_node = create_directories( 20012976Snikos.nikoleris@arm.com options, bootmem, ruby_system, system) 20112598Snikos.nikoleris@arm.com dir_cntrl_nodes = mem_dir_cntrl_nodes[:] 20212598Snikos.nikoleris@arm.com if rom_dir_cntrl_node is not None: 20312598Snikos.nikoleris@arm.com dir_cntrl_nodes.append(rom_dir_cntrl_node) 20412065Snikos.nikoleris@arm.com for dir_cntrl in dir_cntrl_nodes: 20510311Snilay@cs.wisc.edu # Connect the directory controllers and the network 20611022Sjthestness@gmail.com dir_cntrl.requestToDir = MessageBuffer() 20711022Sjthestness@gmail.com dir_cntrl.requestToDir.slave = ruby_system.network.master 20811022Sjthestness@gmail.com dir_cntrl.responseToDir = MessageBuffer() 20911022Sjthestness@gmail.com dir_cntrl.responseToDir.slave = ruby_system.network.master 21011022Sjthestness@gmail.com dir_cntrl.responseFromDir = MessageBuffer() 21111022Sjthestness@gmail.com dir_cntrl.responseFromDir.master = ruby_system.network.slave 21211022Sjthestness@gmail.com dir_cntrl.forwardFromDir = MessageBuffer() 21311022Sjthestness@gmail.com dir_cntrl.forwardFromDir.master = ruby_system.network.slave 21411022Sjthestness@gmail.com dir_cntrl.responseFromMemory = MessageBuffer() 21510311Snilay@cs.wisc.edu 21610311Snilay@cs.wisc.edu 2178929Snilay@cs.wisc.edu for i, dma_port in enumerate(dma_ports): 2186911SBrad.Beckmann@amd.com # 2196911SBrad.Beckmann@amd.com # Create the Ruby objects associated with the dma controller 2206911SBrad.Beckmann@amd.com # 2216911SBrad.Beckmann@amd.com dma_seq = DMASequencer(version = i, 22210519Snilay@cs.wisc.edu ruby_system = ruby_system, 22310519Snilay@cs.wisc.edu slave = dma_port) 22410917Sbrandon.potter@amd.com 2256911SBrad.Beckmann@amd.com dma_cntrl = DMA_Controller(version = i, 2268477Snilay@cs.wisc.edu dma_sequencer = dma_seq, 2279841Snilay@cs.wisc.edu transitions_per_cycle = options.ports, 2288477Snilay@cs.wisc.edu ruby_system = ruby_system) 2296911SBrad.Beckmann@amd.com 2309468Smalek.musleh@gmail.com exec("ruby_system.dma_cntrl%d = dma_cntrl" % i) 2316911SBrad.Beckmann@amd.com dma_cntrl_nodes.append(dma_cntrl) 2328257SBrad.Beckmann@amd.com 23310519Snilay@cs.wisc.edu # Connect the dma controller to the network 23411022Sjthestness@gmail.com dma_cntrl.mandatoryQueue = MessageBuffer() 23511022Sjthestness@gmail.com dma_cntrl.responseFromDir = MessageBuffer() 23611022Sjthestness@gmail.com dma_cntrl.responseFromDir.slave = ruby_system.network.master 23711022Sjthestness@gmail.com dma_cntrl.reqToDir = MessageBuffer() 23811022Sjthestness@gmail.com dma_cntrl.reqToDir.master = ruby_system.network.slave 23911022Sjthestness@gmail.com dma_cntrl.respToDir = MessageBuffer() 24011022Sjthestness@gmail.com dma_cntrl.respToDir.master = ruby_system.network.slave 24111022Sjthestness@gmail.com dma_cntrl.triggerQueue = MessageBuffer(ordered = True) 24210519Snilay@cs.wisc.edu 24310311Snilay@cs.wisc.edu 2446911SBrad.Beckmann@amd.com all_cntrls = l1_cntrl_nodes + \ 2456911SBrad.Beckmann@amd.com l2_cntrl_nodes + \ 2466911SBrad.Beckmann@amd.com dir_cntrl_nodes + \ 2476911SBrad.Beckmann@amd.com dma_cntrl_nodes 2486911SBrad.Beckmann@amd.com 24910519Snilay@cs.wisc.edu # Create the io controller and the sequencer 25010519Snilay@cs.wisc.edu if full_system: 25110519Snilay@cs.wisc.edu io_seq = DMASequencer(version=len(dma_ports), ruby_system=ruby_system) 25210519Snilay@cs.wisc.edu ruby_system._io_port = io_seq 25310519Snilay@cs.wisc.edu io_controller = DMA_Controller(version = len(dma_ports), 25410519Snilay@cs.wisc.edu dma_sequencer = io_seq, 25510519Snilay@cs.wisc.edu ruby_system = ruby_system) 25610519Snilay@cs.wisc.edu ruby_system.io_controller = io_controller 25710519Snilay@cs.wisc.edu 25810519Snilay@cs.wisc.edu # Connect the dma controller to the network 25911022Sjthestness@gmail.com io_controller.mandatoryQueue = MessageBuffer() 26011022Sjthestness@gmail.com io_controller.responseFromDir = MessageBuffer() 26111022Sjthestness@gmail.com io_controller.responseFromDir.slave = ruby_system.network.master 26211022Sjthestness@gmail.com io_controller.reqToDir = MessageBuffer() 26311022Sjthestness@gmail.com io_controller.reqToDir.master = ruby_system.network.slave 26411022Sjthestness@gmail.com io_controller.respToDir = MessageBuffer() 26511022Sjthestness@gmail.com io_controller.respToDir.master = ruby_system.network.slave 26611022Sjthestness@gmail.com io_controller.triggerQueue = MessageBuffer(ordered = True) 26710519Snilay@cs.wisc.edu 26810519Snilay@cs.wisc.edu all_cntrls = all_cntrls + [io_controller] 26910519Snilay@cs.wisc.edu 27011065Snilay@cs.wisc.edu ruby_system.network.number_of_virtual_networks = 3 2719100SBrad.Beckmann@amd.com topology = create_topology(all_cntrls, options) 27212598Snikos.nikoleris@arm.com return (cpu_sequencers, mem_dir_cntrl_nodes, topology) 273