module.cc revision 13291:ccbae1f89cd3
1/*
2 * Copyright 2018 Google, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution;
11 * neither the name of the copyright holders nor the names of its
12 * contributors may be used to endorse or promote products derived from
13 * this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * Authors: Gabe Black
28 */
29
30#include "systemc/core/module.hh"
31
32#include <cassert>
33
34#include "base/logging.hh"
35#include "systemc/ext/core/sc_export.hh"
36#include "systemc/ext/core/sc_port.hh"
37#include "systemc/ext/utils/sc_report_handler.hh"
38
39namespace sc_gem5
40{
41
42namespace
43{
44
45std::list<Module *> _modules;
46Module *_new_module;
47
48} // anonymous namespace
49
50Module::Module(const char *name) :
51    _name(name), _sc_mod(nullptr), _obj(nullptr), _ended(false),
52    _deprecatedConstructor(false), bindingIndex(0)
53{
54    panic_if(_new_module, "Previous module not finished.\n");
55    _new_module = this;
56}
57
58Module::~Module()
59{
60    // Aborted module construction?
61    if (_new_module == this)
62        _new_module = nullptr;
63
64    // Attempt to pop now in case we're at the top of the stack, so that
65    // a stale pointer to us isn't left floating around for somebody to trip
66    // on.
67    pop();
68
69    allModules.remove(this);
70}
71
72void
73Module::finish(Object *this_obj)
74{
75    assert(!_obj);
76    _obj = this_obj;
77    _modules.push_back(this);
78    pushParentModule(this);
79    try {
80        _new_module = nullptr;
81        // This is called from the constructor of this_obj, so it can't use
82        // dynamic cast.
83        sc_mod(static_cast<::sc_core::sc_module *>(this_obj->sc_obj()));
84        allModules.emplace_back(this);
85    } catch (...) {
86        popParentModule();
87        throw;
88    }
89}
90
91void
92Module::pop()
93{
94    if (_modules.empty() || _modules.back() != this)
95        return;
96
97    panic_if(_new_module, "Pop with unfinished module.\n");
98
99    _modules.pop_back();
100    popParentModule();
101}
102
103void
104Module::bindPorts(std::vector<const ::sc_core::sc_bind_proxy *> &proxies)
105{
106    panic_if(proxies.size() > ports.size(),
107            "Trying to bind %d interfaces/ports to %d ports.\n",
108            proxies.size(), ports.size());
109
110    auto proxyIt = proxies.begin();
111    auto portIt = ports.begin();
112    portIt += bindingIndex;
113    for (; proxyIt != proxies.end(); proxyIt++, portIt++) {
114        auto proxy = *proxyIt;
115        auto port = *portIt;
116        if (proxy->interface())
117            port->vbind(*proxy->interface());
118        else
119            port->vbind(*proxy->port());
120    }
121    bindingIndex += proxies.size();
122}
123
124void
125Module::beforeEndOfElaboration()
126{
127    pushParentModule(this);
128    try {
129        _sc_mod->before_end_of_elaboration();
130        for (auto e: exports)
131            e->before_end_of_elaboration();
132    } catch (...) {
133        popParentModule();
134        throw;
135    }
136    popParentModule();
137}
138
139void
140Module::endOfElaboration()
141{
142    if (_deprecatedConstructor && !_ended) {
143        std::string msg = csprintf("module '%s'", name());
144        SC_REPORT_WARNING("(W509) module construction not properly completed: "
145                "did you forget to add a sc_module_name parameter to "
146                "your module constructor?", msg.c_str());
147    }
148    pushParentModule(this);
149    try {
150        _sc_mod->end_of_elaboration();
151        for (auto e: exports)
152            e->end_of_elaboration();
153    } catch (...) {
154        popParentModule();
155        throw;
156    }
157    popParentModule();
158}
159
160void
161Module::startOfSimulation()
162{
163    pushParentModule(this);
164    try {
165        _sc_mod->start_of_simulation();
166        for (auto e: exports)
167            e->start_of_simulation();
168    } catch (...) {
169        popParentModule();
170        throw;
171    }
172    popParentModule();
173}
174
175void
176Module::endOfSimulation()
177{
178    pushParentModule(this);
179    try {
180        _sc_mod->end_of_simulation();
181        for (auto e: exports)
182            e->end_of_simulation();
183    } catch(...) {
184        popParentModule();
185        throw;
186    }
187    popParentModule();
188}
189
190Module *
191currentModule()
192{
193    if (_modules.empty())
194        return nullptr;
195    return _modules.back();
196}
197
198Module *
199newModuleChecked()
200{
201    if (!_new_module) {
202        SC_REPORT_ERROR("(E533) module name stack is empty: "
203                "did you forget to add a sc_module_name parameter to "
204                "your module constructor?", nullptr);
205    }
206    return _new_module;
207}
208
209Module *
210newModule()
211{
212    return _new_module;
213}
214
215std::list<Module *> allModules;
216
217} // namespace sc_gem5
218