112047Schristian.menard@tu-dresden.de/*
212047Schristian.menard@tu-dresden.de * Copyright (c) 2015, University of Kaiserslautern
312047Schristian.menard@tu-dresden.de * Copyright (c) 2016, Dresden University of Technology (TU Dresden)
412047Schristian.menard@tu-dresden.de * All rights reserved.
512047Schristian.menard@tu-dresden.de *
612047Schristian.menard@tu-dresden.de * Redistribution and use in source and binary forms, with or without
712047Schristian.menard@tu-dresden.de * modification, are permitted provided that the following conditions are
812047Schristian.menard@tu-dresden.de * met:
912047Schristian.menard@tu-dresden.de *
1012047Schristian.menard@tu-dresden.de * 1. Redistributions of source code must retain the above copyright notice,
1112047Schristian.menard@tu-dresden.de *    this list of conditions and the following disclaimer.
1212047Schristian.menard@tu-dresden.de *
1312047Schristian.menard@tu-dresden.de * 2. Redistributions in binary form must reproduce the above copyright
1412047Schristian.menard@tu-dresden.de *    notice, this list of conditions and the following disclaimer in the
1512047Schristian.menard@tu-dresden.de *    documentation and/or other materials provided with the distribution.
1612047Schristian.menard@tu-dresden.de *
1712047Schristian.menard@tu-dresden.de * 3. Neither the name of the copyright holder nor the names of its
1812047Schristian.menard@tu-dresden.de *    contributors may be used to endorse or promote products derived from
1912047Schristian.menard@tu-dresden.de *    this software without specific prior written permission.
2012047Schristian.menard@tu-dresden.de *
2112047Schristian.menard@tu-dresden.de * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2212047Schristian.menard@tu-dresden.de * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2312047Schristian.menard@tu-dresden.de * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2412047Schristian.menard@tu-dresden.de * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
2512047Schristian.menard@tu-dresden.de * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2612047Schristian.menard@tu-dresden.de * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2712047Schristian.menard@tu-dresden.de * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2812047Schristian.menard@tu-dresden.de * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2912047Schristian.menard@tu-dresden.de * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3012047Schristian.menard@tu-dresden.de * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3112047Schristian.menard@tu-dresden.de * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3212047Schristian.menard@tu-dresden.de *
3312047Schristian.menard@tu-dresden.de * Authors: Matthias Jung
3412047Schristian.menard@tu-dresden.de *          Abdul Mutaal Ahmad
3512047Schristian.menard@tu-dresden.de *          Christian Menard
3612047Schristian.menard@tu-dresden.de */
3712047Schristian.menard@tu-dresden.de
3812047Schristian.menard@tu-dresden.de/**
3912047Schristian.menard@tu-dresden.de * @file
4012047Schristian.menard@tu-dresden.de *
4112047Schristian.menard@tu-dresden.de *  Example top level file for SystemC-TLM integration with C++-only
4212047Schristian.menard@tu-dresden.de *  instantiation.
4312047Schristian.menard@tu-dresden.de *
4412047Schristian.menard@tu-dresden.de */
4512047Schristian.menard@tu-dresden.de
4612047Schristian.menard@tu-dresden.de#include <systemc>
4712047Schristian.menard@tu-dresden.de#include <tlm>
4812047Schristian.menard@tu-dresden.de
4912047Schristian.menard@tu-dresden.de#include "sc_master_port.hh"
5012047Schristian.menard@tu-dresden.de#include "sc_slave_port.hh"
5112047Schristian.menard@tu-dresden.de#include "sim/cxx_config_ini.hh"
5212047Schristian.menard@tu-dresden.de#include "sim/init_signals.hh"
5312047Schristian.menard@tu-dresden.de#include "sim/stat_control.hh"
5412047Schristian.menard@tu-dresden.de#include "sim_control.hh"
5512047Schristian.menard@tu-dresden.de#include "stats.hh"
5612047Schristian.menard@tu-dresden.de
5712047Schristian.menard@tu-dresden.de// Define global string variable decalred in stats.hh
5812047Schristian.menard@tu-dresden.destd::string filename = "m5out/stats-systemc.txt";
5912047Schristian.menard@tu-dresden.de
6012047Schristian.menard@tu-dresden.denamespace Gem5SystemC
6112047Schristian.menard@tu-dresden.de{
6212047Schristian.menard@tu-dresden.de
6312047Schristian.menard@tu-dresden.deGem5SimControl* Gem5SimControl::instance = nullptr;
6412047Schristian.menard@tu-dresden.de
6512047Schristian.menard@tu-dresden.deGem5SimControl::Gem5SimControl(sc_core::sc_module_name name,
6612047Schristian.menard@tu-dresden.de                               const std::string& configFile,
6712047Schristian.menard@tu-dresden.de                               uint64_t simulationEnd,
6812047Schristian.menard@tu-dresden.de                               const std::string& gem5DebugFlags)
6912047Schristian.menard@tu-dresden.de  : Gem5SystemC::Module(name),
7012047Schristian.menard@tu-dresden.de    simulationEnd(simulationEnd)
7112047Schristian.menard@tu-dresden.de{
7212047Schristian.menard@tu-dresden.de    SC_THREAD(run);
7312047Schristian.menard@tu-dresden.de
7412047Schristian.menard@tu-dresden.de    if (instance != nullptr) {
7512047Schristian.menard@tu-dresden.de        panic("Tried to instantiate Gem5SimControl more than once!\n");
7612047Schristian.menard@tu-dresden.de    }
7712047Schristian.menard@tu-dresden.de    instance = this;
7812047Schristian.menard@tu-dresden.de
7912047Schristian.menard@tu-dresden.de    cxxConfigInit();
8012047Schristian.menard@tu-dresden.de
8112047Schristian.menard@tu-dresden.de    // register the systemc slave and master port handler
8212047Schristian.menard@tu-dresden.de    ExternalSlave::registerHandler("tlm_slave", new SCSlavePortHandler(*this));
8312047Schristian.menard@tu-dresden.de    ExternalMaster::registerHandler("tlm_master",
8412047Schristian.menard@tu-dresden.de                                    new SCMasterPortHandler(*this));
8512047Schristian.menard@tu-dresden.de
8612047Schristian.menard@tu-dresden.de    Trace::setDebugLogger(&logger);
8712047Schristian.menard@tu-dresden.de
8812047Schristian.menard@tu-dresden.de    Gem5SystemC::setTickFrequency();
8912183Sjungma@eit.uni-kl.de    assert(sc_core::sc_get_time_resolution()
9012183Sjungma@eit.uni-kl.de                    == sc_core::sc_time(1,sc_core::SC_PS));
9112047Schristian.menard@tu-dresden.de
9212047Schristian.menard@tu-dresden.de    Gem5SystemC::Module::setupEventQueues(*this);
9312047Schristian.menard@tu-dresden.de    initSignals();
9412047Schristian.menard@tu-dresden.de
9512047Schristian.menard@tu-dresden.de    Stats::initSimStats();
9612047Schristian.menard@tu-dresden.de    Stats::registerHandlers(CxxConfig::statsReset, CxxConfig::statsDump);
9712047Schristian.menard@tu-dresden.de
9812047Schristian.menard@tu-dresden.de    Trace::enable();
9912047Schristian.menard@tu-dresden.de
10012047Schristian.menard@tu-dresden.de    CxxConfigFileBase* conf = new CxxIniFile();
10112047Schristian.menard@tu-dresden.de
10212047Schristian.menard@tu-dresden.de    if (configFile.empty()) {
10312047Schristian.menard@tu-dresden.de        std::cerr << "No gem5 config file specified!\n";
10412047Schristian.menard@tu-dresden.de        std::exit(EXIT_FAILURE);
10512047Schristian.menard@tu-dresden.de    }
10612047Schristian.menard@tu-dresden.de
10712047Schristian.menard@tu-dresden.de    if (!conf->load(configFile.c_str())) {
10812047Schristian.menard@tu-dresden.de        std::cerr << "Can't open config file: " << configFile << '\n';
10912047Schristian.menard@tu-dresden.de        std::exit(EXIT_FAILURE);
11012047Schristian.menard@tu-dresden.de    }
11112047Schristian.menard@tu-dresden.de
11212047Schristian.menard@tu-dresden.de    config_manager = new CxxConfigManager(*conf);
11312047Schristian.menard@tu-dresden.de
11412047Schristian.menard@tu-dresden.de    // parse debug flags string and clear/set flags accordingly
11512047Schristian.menard@tu-dresden.de    std::stringstream ss;
11612047Schristian.menard@tu-dresden.de    ss.str(gem5DebugFlags);
11712047Schristian.menard@tu-dresden.de    std::string flag;
11812047Schristian.menard@tu-dresden.de    while (std::getline(ss, flag, ' ')) {
11912047Schristian.menard@tu-dresden.de        if (flag.at(0) == '-') {
12012047Schristian.menard@tu-dresden.de            flag.erase(0, 1); // remove the '-'
12112047Schristian.menard@tu-dresden.de            clearDebugFlag(flag.c_str());
12212047Schristian.menard@tu-dresden.de        }
12312047Schristian.menard@tu-dresden.de        else {
12412047Schristian.menard@tu-dresden.de            setDebugFlag(flag.c_str());
12512047Schristian.menard@tu-dresden.de        }
12612047Schristian.menard@tu-dresden.de    }
12712047Schristian.menard@tu-dresden.de
12812047Schristian.menard@tu-dresden.de    CxxConfig::statsEnable();
12912047Schristian.menard@tu-dresden.de    getEventQueue(0)->dump();
13012047Schristian.menard@tu-dresden.de
13112047Schristian.menard@tu-dresden.de    try {
13212047Schristian.menard@tu-dresden.de        config_manager->instantiate();
13312047Schristian.menard@tu-dresden.de    } catch (CxxConfigManager::Exception &e) {
13412047Schristian.menard@tu-dresden.de        std::cerr << "Config problem in sim object "
13512047Schristian.menard@tu-dresden.de                  << e.name << ": " << e.message << "\n";
13612047Schristian.menard@tu-dresden.de        std::exit(EXIT_FAILURE);
13712047Schristian.menard@tu-dresden.de    }
13812047Schristian.menard@tu-dresden.de}
13912047Schristian.menard@tu-dresden.de
14012047Schristian.menard@tu-dresden.devoid
14112047Schristian.menard@tu-dresden.deGem5SimControl::end_of_elaboration()
14212047Schristian.menard@tu-dresden.de{
14312047Schristian.menard@tu-dresden.de    try {
14412047Schristian.menard@tu-dresden.de        config_manager->initState();
14512047Schristian.menard@tu-dresden.de        config_manager->startup();
14612047Schristian.menard@tu-dresden.de    } catch (CxxConfigManager::Exception &e) {
14712047Schristian.menard@tu-dresden.de        std::cerr << "Config problem in sim object "
14812047Schristian.menard@tu-dresden.de            << e.name << ": " << e.message << "\n";
14912047Schristian.menard@tu-dresden.de        std::exit(EXIT_FAILURE);
15012047Schristian.menard@tu-dresden.de    }
15112047Schristian.menard@tu-dresden.de}
15212047Schristian.menard@tu-dresden.de
15312047Schristian.menard@tu-dresden.devoid
15412047Schristian.menard@tu-dresden.deGem5SimControl::run()
15512047Schristian.menard@tu-dresden.de{
15612047Schristian.menard@tu-dresden.de    // notify callback
15712047Schristian.menard@tu-dresden.de    beforeSimulate();
15812047Schristian.menard@tu-dresden.de
15912047Schristian.menard@tu-dresden.de    GlobalSimLoopExitEvent *exit_event = NULL;
16012047Schristian.menard@tu-dresden.de
16112047Schristian.menard@tu-dresden.de    if (simulationEnd == 0) {
16212047Schristian.menard@tu-dresden.de        exit_event = simulate();
16312047Schristian.menard@tu-dresden.de    } else {
16412047Schristian.menard@tu-dresden.de        exit_event = simulate(simulationEnd);
16512047Schristian.menard@tu-dresden.de    }
16612047Schristian.menard@tu-dresden.de
16712047Schristian.menard@tu-dresden.de    std::cerr << "Exit at tick " << curTick()
16812047Schristian.menard@tu-dresden.de              << ", cause: " << exit_event->getCause() << '\n';
16912047Schristian.menard@tu-dresden.de
17012047Schristian.menard@tu-dresden.de    getEventQueue(0)->dump();
17112047Schristian.menard@tu-dresden.de
17212047Schristian.menard@tu-dresden.de    // notify callback
17312047Schristian.menard@tu-dresden.de    afterSimulate();
17412047Schristian.menard@tu-dresden.de
17512047Schristian.menard@tu-dresden.de#if TRY_CLEAN_DELETE
17612047Schristian.menard@tu-dresden.de    config_manager->deleteObjects();
17712047Schristian.menard@tu-dresden.de#endif
17812047Schristian.menard@tu-dresden.de}
17912047Schristian.menard@tu-dresden.de
18012047Schristian.menard@tu-dresden.devoid
18112047Schristian.menard@tu-dresden.deGem5SimControl::registerSlavePort(const std::string& name, SCSlavePort* port)
18212047Schristian.menard@tu-dresden.de{
18312047Schristian.menard@tu-dresden.de    if (slavePorts.find(name) == slavePorts.end()) {
18412047Schristian.menard@tu-dresden.de        slavePorts[name] = port;
18512047Schristian.menard@tu-dresden.de    } else {
18612047Schristian.menard@tu-dresden.de        std::cerr << "Slave Port " << name << " is already registered!\n";
18712047Schristian.menard@tu-dresden.de        std::exit(EXIT_FAILURE);
18812047Schristian.menard@tu-dresden.de    }
18912047Schristian.menard@tu-dresden.de}
19012047Schristian.menard@tu-dresden.de
19112047Schristian.menard@tu-dresden.devoid
19212047Schristian.menard@tu-dresden.deGem5SimControl::registerMasterPort(const std::string& name, SCMasterPort* port)
19312047Schristian.menard@tu-dresden.de{
19412047Schristian.menard@tu-dresden.de    if (masterPorts.find(name) == masterPorts.end()) {
19512047Schristian.menard@tu-dresden.de        masterPorts[name] = port;
19612047Schristian.menard@tu-dresden.de    } else {
19712047Schristian.menard@tu-dresden.de        std::cerr << "Master Port " << name << " is already registered!\n";
19812047Schristian.menard@tu-dresden.de        std::exit(EXIT_FAILURE);
19912047Schristian.menard@tu-dresden.de    }
20012047Schristian.menard@tu-dresden.de}
20112047Schristian.menard@tu-dresden.de
20212047Schristian.menard@tu-dresden.deSCSlavePort*
20312047Schristian.menard@tu-dresden.deGem5SimControl::getSlavePort(const std::string& name)
20412047Schristian.menard@tu-dresden.de{
20512047Schristian.menard@tu-dresden.de    if (slavePorts.find(name) == slavePorts.end()) {
20612047Schristian.menard@tu-dresden.de        std::cerr << "Slave Port " << name << " was not found!\n";
20712047Schristian.menard@tu-dresden.de        std::exit(EXIT_FAILURE);
20812047Schristian.menard@tu-dresden.de    }
20912047Schristian.menard@tu-dresden.de
21012047Schristian.menard@tu-dresden.de    return slavePorts.at(name);
21112047Schristian.menard@tu-dresden.de}
21212047Schristian.menard@tu-dresden.de
21312047Schristian.menard@tu-dresden.deSCMasterPort*
21412047Schristian.menard@tu-dresden.deGem5SimControl::getMasterPort(const std::string& name)
21512047Schristian.menard@tu-dresden.de{
21612047Schristian.menard@tu-dresden.de    if (masterPorts.find(name) == masterPorts.end()) {
21712047Schristian.menard@tu-dresden.de        std::cerr << "Master Port " << name << " was not found!\n";
21812047Schristian.menard@tu-dresden.de        std::exit(EXIT_FAILURE);
21912047Schristian.menard@tu-dresden.de    }
22012047Schristian.menard@tu-dresden.de
22112047Schristian.menard@tu-dresden.de    return masterPorts.at(name);
22212047Schristian.menard@tu-dresden.de}
22312047Schristian.menard@tu-dresden.de
22412047Schristian.menard@tu-dresden.de}
225