# Copyright (c) 2021 The Regents of the University of California
# All rights reserved.
#
# 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.

"""
This tests the gem5 memory components with a simple traffic generator.

TODO: At present all the Single Channel memory components are tested. This
      should be expanded to included DRAMSIM3 memory systems.
"""

from testlib import *


def test_memory(
    generator: str,
    generator_cores: str,
    cache: str,
    module: str,
    memory: str,
    *args,
) -> None:

    name = (
        "test-memory-"
        + f"{generator}-{generator_cores}-{cache}-{module}-{memory}"
    )
    for arg in args:
        name += "-" + arg

    gem5_verify_config(
        name=name,
        fixtures=(),
        verifiers=(),
        config=joinpath(
            config.base_dir,
            "tests",
            "gem5",
            "traffic_gen",
            "simple_traffic_run.py",
        ),
        config_args=[generator, generator_cores, cache, module, memory]
        + list(args),
        valid_isas=(constants.all_compiled_tag,),
        valid_hosts=constants.supported_hosts,
        length=constants.quick_tag,
    )


cache_classes = ["NoCache", "PrivateL1", "PrivateL1PrivateL2", "MESITwoLevel"]
memory_classes = [
    "SingleChannelDDR3_1600",
    "SingleChannelDDR3_2133",
    "SingleChannelDDR4_2400",
    "SingleChannelLPDDR3_1600",
    "SingleChannelHBM",
    "DualChannelDDR3_1600",
    "DualChannelDDR3_2133",
    "DualChannelDDR4_2400",
    "DualChannelLPDDR3_1600",
    "HBM2Stack",
]


def create_single_core_tests(module, memory_classes):
    generator_classes = ["LinearGenerator", "RandomGenerator", "GUPSGenerator"]
    for generator_class in generator_classes:
        for cache_class in cache_classes:
            for memory_class in memory_classes:
                test_memory(
                    generator_class,
                    "1",
                    cache_class,
                    module,
                    memory_class,
                    "512MiB",
                )


def create_dual_core_tests(module, memory_classes):
    generator_classes = ["GUPSGeneratorEP", "GUPSGeneratorPAR"]
    for generator_class in generator_classes:
        for cache_class in cache_classes:
            for memory_class in memory_classes:
                test_memory(
                    generator_class,
                    "2",
                    cache_class,
                    module,
                    memory_class,
                    "512MiB",
                )


create_single_core_tests("gem5.components.memory", memory_classes)
create_dual_core_tests("gem5.components.memory", memory_classes)
