module.cc revision 13317
112852Sgabeblack@google.com/*
212852Sgabeblack@google.com * Copyright 2018 Google, Inc.
312852Sgabeblack@google.com *
412852Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
512852Sgabeblack@google.com * modification, are permitted provided that the following conditions are
612852Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
712852Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
812852Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
912852Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1012852Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1112852Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1212852Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1312852Sgabeblack@google.com * this software without specific prior written permission.
1412852Sgabeblack@google.com *
1512852Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1612852Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1712852Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1812852Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1912852Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2012852Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2112852Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2212852Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2312852Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2412852Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2512852Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2612852Sgabeblack@google.com *
2712852Sgabeblack@google.com * Authors: Gabe Black
2812852Sgabeblack@google.com */
2912852Sgabeblack@google.com
3012997Sgabeblack@google.com#include "systemc/core/module.hh"
3112997Sgabeblack@google.com
3212997Sgabeblack@google.com#include <cassert>
3312997Sgabeblack@google.com
3412997Sgabeblack@google.com#include "base/logging.hh"
3513335Sgabeblack@google.com#include "systemc/ext/core/messages.hh"
3612997Sgabeblack@google.com#include "systemc/ext/core/sc_export.hh"
3712997Sgabeblack@google.com#include "systemc/ext/core/sc_port.hh"
3812997Sgabeblack@google.com#include "systemc/ext/utils/sc_report_handler.hh"
3913324Sgabeblack@google.com
4012852Sgabeblack@google.comnamespace sc_gem5
4113312Sgabeblack@google.com{
4212852Sgabeblack@google.com
4312852Sgabeblack@google.comnamespace
4412852Sgabeblack@google.com{
4512852Sgabeblack@google.com
4612997Sgabeblack@google.comstd::list<Module *> _modules;
4712997Sgabeblack@google.comModule *_new_module;
4812997Sgabeblack@google.com
4912997Sgabeblack@google.com} // anonymous namespace
5012997Sgabeblack@google.com
5112997Sgabeblack@google.comUniqueNameGen globalNameGen;
5212997Sgabeblack@google.com
5312997Sgabeblack@google.comModule::Module(const char *name) :
5412852Sgabeblack@google.com    _name(name), _sc_mod(nullptr), _obj(nullptr), _ended(false),
5512997Sgabeblack@google.com    _deprecatedConstructor(false), bindingIndex(0)
5612997Sgabeblack@google.com{
5712852Sgabeblack@google.com    panic_if(_new_module, "Previous module not finished.\n");
5812997Sgabeblack@google.com    _new_module = this;
5912852Sgabeblack@google.com}
6012852Sgabeblack@google.com
6112852Sgabeblack@google.comModule::~Module()
6212997Sgabeblack@google.com{
6312997Sgabeblack@google.com    // Aborted module construction?
6412997Sgabeblack@google.com    if (_new_module == this)
6512852Sgabeblack@google.com        _new_module = nullptr;
6613324Sgabeblack@google.com
6713324Sgabeblack@google.com    // Attempt to pop now in case we're at the top of the stack, so that
6813324Sgabeblack@google.com    // a stale pointer to us isn't left floating around for somebody to trip
6913312Sgabeblack@google.com    // on.
7012997Sgabeblack@google.com    pop();
7112997Sgabeblack@google.com
7213312Sgabeblack@google.com    allModules.remove(this);
7313401Sgabeblack@google.com}
7412997Sgabeblack@google.com
7512997Sgabeblack@google.comvoid
7612997Sgabeblack@google.comModule::finish(Object *this_obj)
7713312Sgabeblack@google.com{
7812997Sgabeblack@google.com    assert(!_obj);
7912997Sgabeblack@google.com    _obj = this_obj;
8013312Sgabeblack@google.com    _modules.push_back(this);
8113312Sgabeblack@google.com    pushParentModule(this);
8212997Sgabeblack@google.com    try {
8312997Sgabeblack@google.com        _new_module = nullptr;
8412997Sgabeblack@google.com        // This is called from the constructor of this_obj, so it can't use
8512997Sgabeblack@google.com        // dynamic cast.
8612997Sgabeblack@google.com        sc_mod(static_cast<::sc_core::sc_module *>(this_obj->sc_obj()));
8713312Sgabeblack@google.com        allModules.emplace_back(this);
8813312Sgabeblack@google.com    } catch (...) {
8912997Sgabeblack@google.com        popParentModule();
9013312Sgabeblack@google.com        throw;
9113312Sgabeblack@google.com    }
9212997Sgabeblack@google.com}
9312997Sgabeblack@google.com
9412997Sgabeblack@google.comvoid
9512997Sgabeblack@google.comModule::pop()
9613313Sgabeblack@google.com{
9712997Sgabeblack@google.com    if (_modules.empty() || _modules.back() != this)
9812997Sgabeblack@google.com        return;
9912997Sgabeblack@google.com
10012997Sgabeblack@google.com    panic_if(_new_module, "Pop with unfinished module.\n");
10112997Sgabeblack@google.com
10213312Sgabeblack@google.com    _modules.pop_back();
10312997Sgabeblack@google.com    popParentModule();
10412997Sgabeblack@google.com}
10512997Sgabeblack@google.com
10612997Sgabeblack@google.comvoid
10713312Sgabeblack@google.comModule::bindPorts(std::vector<const ::sc_core::sc_bind_proxy *> &proxies)
10812852Sgabeblack@google.com{
10912852Sgabeblack@google.com    panic_if(proxies.size() > ports.size(),
11012902Sgabeblack@google.com            "Trying to bind %d interfaces/ports to %d ports.\n",
11113313Sgabeblack@google.com            proxies.size(), ports.size());
11212902Sgabeblack@google.com
11312902Sgabeblack@google.com    auto proxyIt = proxies.begin();
11413401Sgabeblack@google.com    auto portIt = ports.begin();
11513313Sgabeblack@google.com    portIt += bindingIndex;
11613313Sgabeblack@google.com    for (; proxyIt != proxies.end(); proxyIt++, portIt++) {
11713313Sgabeblack@google.com        auto proxy = *proxyIt;
11813313Sgabeblack@google.com        auto port = *portIt;
11913313Sgabeblack@google.com        if (proxy->interface())
12012902Sgabeblack@google.com            port->vbind(*proxy->interface());
12112902Sgabeblack@google.com        else
12212852Sgabeblack@google.com            port->vbind(*proxy->port());
12312997Sgabeblack@google.com    }
12412852Sgabeblack@google.com    bindingIndex += proxies.size();
12513312Sgabeblack@google.com}
12612997Sgabeblack@google.com
12712997Sgabeblack@google.comvoid
12812997Sgabeblack@google.comModule::beforeEndOfElaboration()
12912852Sgabeblack@google.com{
13012852Sgabeblack@google.com    pushParentModule(this);
13112852Sgabeblack@google.com    try {
13212997Sgabeblack@google.com        _sc_mod->before_end_of_elaboration();
13312852Sgabeblack@google.com        for (auto e: exports)
13413324Sgabeblack@google.com            e->before_end_of_elaboration();
13513324Sgabeblack@google.com    } catch (...) {
13613324Sgabeblack@google.com        popParentModule();
13713401Sgabeblack@google.com        throw;
13812997Sgabeblack@google.com    }
13912997Sgabeblack@google.com    popParentModule();
14012997Sgabeblack@google.com}
14112852Sgabeblack@google.com
14212852Sgabeblack@google.comvoid
14312852Sgabeblack@google.comModule::endOfElaboration()
14412997Sgabeblack@google.com{
14512997Sgabeblack@google.com    if (_deprecatedConstructor && !_ended) {
14612852Sgabeblack@google.com        std::string msg = csprintf("module '%s'", name());
14713324Sgabeblack@google.com        SC_REPORT_WARNING(sc_core::SC_ID_END_MODULE_NOT_CALLED_, msg.c_str());
14813324Sgabeblack@google.com    }
14913324Sgabeblack@google.com    pushParentModule(this);
15013401Sgabeblack@google.com    try {
15113312Sgabeblack@google.com        _sc_mod->end_of_elaboration();
15213312Sgabeblack@google.com        for (auto e: exports)
15312997Sgabeblack@google.com            e->end_of_elaboration();
15412852Sgabeblack@google.com    } catch (...) {
15512852Sgabeblack@google.com        popParentModule();
15612852Sgabeblack@google.com        throw;
15712997Sgabeblack@google.com    }
15812852Sgabeblack@google.com    popParentModule();
15913312Sgabeblack@google.com}
16012997Sgabeblack@google.com
16112997Sgabeblack@google.comvoid
16212997Sgabeblack@google.comModule::startOfSimulation()
16312852Sgabeblack@google.com{
16412852Sgabeblack@google.com    pushParentModule(this);
16512852Sgabeblack@google.com    try {
16612852Sgabeblack@google.com        _sc_mod->start_of_simulation();
16712852Sgabeblack@google.com        for (auto e: exports)
16813324Sgabeblack@google.com            e->start_of_simulation();
16913324Sgabeblack@google.com    } catch (...) {
17013324Sgabeblack@google.com        popParentModule();
17113401Sgabeblack@google.com        throw;
17212997Sgabeblack@google.com    }
17312997Sgabeblack@google.com    popParentModule();
17412997Sgabeblack@google.com}
17512852Sgabeblack@google.com
17612852Sgabeblack@google.comvoid
17712852Sgabeblack@google.comModule::endOfSimulation()
17812997Sgabeblack@google.com{
17912997Sgabeblack@google.com    pushParentModule(this);
18012852Sgabeblack@google.com    try {
18113324Sgabeblack@google.com        _sc_mod->end_of_simulation();
18213324Sgabeblack@google.com        for (auto e: exports)
18313324Sgabeblack@google.com            e->end_of_simulation();
18413401Sgabeblack@google.com    } catch(...) {
18513312Sgabeblack@google.com        popParentModule();
18613312Sgabeblack@google.com        throw;
18712997Sgabeblack@google.com    }
18812852Sgabeblack@google.com    popParentModule();
18912852Sgabeblack@google.com}
19012852Sgabeblack@google.com
19112997Sgabeblack@google.comModule *
19212852Sgabeblack@google.comcurrentModule()
19313312Sgabeblack@google.com{
19412852Sgabeblack@google.com    if (_modules.empty())
19512852Sgabeblack@google.com        return nullptr;
19612852Sgabeblack@google.com    return _modules.back();
19712852Sgabeblack@google.com}
19812852Sgabeblack@google.com
19913324Sgabeblack@google.comModule *
20013324Sgabeblack@google.comnewModuleChecked()
20113324Sgabeblack@google.com{
20213401Sgabeblack@google.com    if (!_new_module)
20312852Sgabeblack@google.com        SC_REPORT_ERROR(sc_core::SC_ID_MODULE_NAME_STACK_EMPTY_, "");
20412852Sgabeblack@google.com    return _new_module;
20512852Sgabeblack@google.com}
20612997Sgabeblack@google.com
20712852Sgabeblack@google.comModule *
20813324Sgabeblack@google.comnewModule()
20913324Sgabeblack@google.com{
21013324Sgabeblack@google.com    return _new_module;
21113401Sgabeblack@google.com}
21212852Sgabeblack@google.com
21312852Sgabeblack@google.comstd::list<Module *> allModules;
21412852Sgabeblack@google.com
21512997Sgabeblack@google.com} // namespace sc_gem5
21612852Sgabeblack@google.com