# Copyright (c) 2014-2015, 2018-2020 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder.  You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import math
import optparse

import m5
from m5.objects import *
from m5.util import addToPath
from m5.stats import periodicStatDump

addToPath('../')

from common import ObjectList
from common import MemConfig

# this script is helpful to sweep the efficiency of a specific memory
# controller configuration, by varying the number of banks accessed,
# and the sequential stride size (how many bytes per activate), and
# observe what bus utilisation (bandwidth) is achieved

parser = optparse.OptionParser()

dram_generators = {
    "DRAM" : lambda x: x.createDram,
    "DRAM_ROTATE" : lambda x: x.createDramRot,
}

# Use a single-channel DDR3-1600 x64 (8x8 topology) by default
parser.add_option("--mem-type", type="choice", default="DDR3_1600_8x8",
                  choices=ObjectList.mem_list.get_names(),
                  help = "type of memory to use")

parser.add_option("--mem-ranks", "-r", type="int", default=1,
                  help = "Number of ranks to iterate across")

parser.add_option("--rd_perc", type="int", default=100,
                  help = "Percentage of read commands")

parser.add_option("--mode", type="choice", default="DRAM",
                  choices=list(dram_generators.keys()),
                  help = "DRAM: Random traffic; \
                          DRAM_ROTATE: Traffic rotating across banks and ranks")

parser.add_option("--addr-map", type="choice",
                  choices=ObjectList.dram_addr_map_list.get_names(),
                  default="RoRaBaCoCh", help = "DRAM address map policy")

(options, args) = parser.parse_args()

if args:
    print("Error: script doesn't take any positional arguments")
    sys.exit(1)

# at the moment we stay with the default open-adaptive page policy,
# and address mapping

# start with the system itself, using a multi-layer 2.0 GHz
# crossbar, delivering 64 bytes / 3 cycles (one header cycle)
# which amounts to 42.7 GByte/s per layer and thus per port
system = System(membus = IOXBar(width = 32))
system.clk_domain = SrcClockDomain(clock = '2.0GHz',
                                   voltage_domain =
                                   VoltageDomain(voltage = '1V'))

# we are fine with 256 MB memory for now
mem_range = AddrRange('256MB')
system.mem_ranges = [mem_range]

# do not worry about reserving space for the backing store
system.mmap_using_noreserve = True

# force a single channel to match the assumptions in the DRAM traffic
# generator
options.mem_channels = 1
options.external_memory_system = 0
options.tlm_memory = 0
options.elastic_trace_en = 0
MemConfig.config_mem(options, system)

# the following assumes that we are using the native DRAM
# controller, check to be sure
if not isinstance(system.mem_ctrls[0], m5.objects.MemCtrl):
    fatal("This script assumes the controller is a MemCtrl subclass")
if not isinstance(system.mem_ctrls[0].dram, m5.objects.DRAMInterface):
    fatal("This script assumes the memory is a DRAMInterface subclass")

# there is no point slowing things down by saving any data
system.mem_ctrls[0].dram.null = True

# Set the address mapping based on input argument
system.mem_ctrls[0].dram.addr_mapping = options.addr_map

# stay in each state for 0.25 ms, long enough to warm things up, and
# short enough to avoid hitting a refresh
period = 250000000

# stay in each state as long as the dump/reset period, use the entire
# range, issue transactions of the right DRAM burst size, and match
# the DRAM maximum bandwidth to ensure that it is saturated

# get the number of banks
nbr_banks = system.mem_ctrls[0].dram.banks_per_rank.value

# determine the burst length in bytes
burst_size = int((system.mem_ctrls[0].dram.devices_per_rank.value *
                  system.mem_ctrls[0].dram.device_bus_width.value *
                  system.mem_ctrls[0].dram.burst_length.value) / 8)

# next, get the page size in bytes
page_size = system.mem_ctrls[0].dram.devices_per_rank.value * \
    system.mem_ctrls[0].dram.device_rowbuffer_size.value

# match the maximum bandwidth of the memory, the parameter is in seconds
# and we need it in ticks (ps)
itt =  getattr(system.mem_ctrls[0].dram.tBURST_MIN, 'value',
               system.mem_ctrls[0].dram.tBURST.value) * 1000000000000

# assume we start at 0
max_addr = mem_range.end

# use min of the page size and 512 bytes as that should be more than
# enough
max_stride = min(512, page_size)

# create a traffic generator, and point it to the file we just created
system.tgen = PyTrafficGen()

# add a communication monitor
system.monitor = CommMonitor()

# connect the traffic generator to the bus via a communication monitor
system.tgen.port = system.monitor.slave
system.monitor.master = system.membus.slave

# connect the system port even if it is not used in this example
system.system_port = system.membus.slave

# every period, dump and reset all stats
periodicStatDump(period)

# run Forrest, run!
root = Root(full_system = False, system = system)
root.system.mem_mode = 'timing'

m5.instantiate()

def trace():
    addr_map = ObjectList.dram_addr_map_list.get(options.addr_map)
    generator = dram_generators[options.mode](system.tgen)
    for stride_size in range(burst_size, max_stride + 1, burst_size):
        for bank in range(1, nbr_banks + 1):
            num_seq_pkts = int(math.ceil(float(stride_size) / burst_size))
            yield generator(period,
                            0, max_addr, burst_size, int(itt), int(itt),
                            options.rd_perc, 0,
                            num_seq_pkts, page_size, nbr_banks, bank,
                            addr_map, options.mem_ranks)
    yield system.tgen.createExit(0)

system.tgen.start(trace())

m5.simulate()

print("DRAM sweep with burst: %d, banks: %d, max stride: %d, request \
       generation period: %d" % (burst_size, nbr_banks, max_stride, itt))
