module.cc revision 13303
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 50UniqueNameGen globalNameGen; 51 52Module::Module(const char *name) : 53 _name(name), _sc_mod(nullptr), _obj(nullptr), _ended(false), 54 _deprecatedConstructor(false), bindingIndex(0) 55{ 56 panic_if(_new_module, "Previous module not finished.\n"); 57 _new_module = this; 58} 59 60Module::~Module() 61{ 62 // Aborted module construction? 63 if (_new_module == this) 64 _new_module = nullptr; 65 66 // Attempt to pop now in case we're at the top of the stack, so that 67 // a stale pointer to us isn't left floating around for somebody to trip 68 // on. 69 pop(); 70 71 allModules.remove(this); 72} 73 74void 75Module::finish(Object *this_obj) 76{ 77 assert(!_obj); 78 _obj = this_obj; 79 _modules.push_back(this); 80 pushParentModule(this); 81 try { 82 _new_module = nullptr; 83 // This is called from the constructor of this_obj, so it can't use 84 // dynamic cast. 85 sc_mod(static_cast<::sc_core::sc_module *>(this_obj->sc_obj())); 86 allModules.emplace_back(this); 87 } catch (...) { 88 popParentModule(); 89 throw; 90 } 91} 92 93void 94Module::pop() 95{ 96 if (_modules.empty() || _modules.back() != this) 97 return; 98 99 panic_if(_new_module, "Pop with unfinished module.\n"); 100 101 _modules.pop_back(); 102 popParentModule(); 103} 104 105void 106Module::bindPorts(std::vector<const ::sc_core::sc_bind_proxy *> &proxies) 107{ 108 panic_if(proxies.size() > ports.size(), 109 "Trying to bind %d interfaces/ports to %d ports.\n", 110 proxies.size(), ports.size()); 111 112 auto proxyIt = proxies.begin(); 113 auto portIt = ports.begin(); 114 portIt += bindingIndex; 115 for (; proxyIt != proxies.end(); proxyIt++, portIt++) { 116 auto proxy = *proxyIt; 117 auto port = *portIt; 118 if (proxy->interface()) 119 port->vbind(*proxy->interface()); 120 else 121 port->vbind(*proxy->port()); 122 } 123 bindingIndex += proxies.size(); 124} 125 126void 127Module::beforeEndOfElaboration() 128{ 129 pushParentModule(this); 130 try { 131 _sc_mod->before_end_of_elaboration(); 132 for (auto e: exports) 133 e->before_end_of_elaboration(); 134 } catch (...) { 135 popParentModule(); 136 throw; 137 } 138 popParentModule(); 139} 140 141void 142Module::endOfElaboration() 143{ 144 if (_deprecatedConstructor && !_ended) { 145 std::string msg = csprintf("module '%s'", name()); 146 SC_REPORT_WARNING("(W509) module construction not properly completed: " 147 "did you forget to add a sc_module_name parameter to " 148 "your module constructor?", msg.c_str()); 149 } 150 pushParentModule(this); 151 try { 152 _sc_mod->end_of_elaboration(); 153 for (auto e: exports) 154 e->end_of_elaboration(); 155 } catch (...) { 156 popParentModule(); 157 throw; 158 } 159 popParentModule(); 160} 161 162void 163Module::startOfSimulation() 164{ 165 pushParentModule(this); 166 try { 167 _sc_mod->start_of_simulation(); 168 for (auto e: exports) 169 e->start_of_simulation(); 170 } catch (...) { 171 popParentModule(); 172 throw; 173 } 174 popParentModule(); 175} 176 177void 178Module::endOfSimulation() 179{ 180 pushParentModule(this); 181 try { 182 _sc_mod->end_of_simulation(); 183 for (auto e: exports) 184 e->end_of_simulation(); 185 } catch(...) { 186 popParentModule(); 187 throw; 188 } 189 popParentModule(); 190} 191 192Module * 193currentModule() 194{ 195 if (_modules.empty()) 196 return nullptr; 197 return _modules.back(); 198} 199 200Module * 201newModuleChecked() 202{ 203 if (!_new_module) { 204 SC_REPORT_ERROR("(E533) module name stack is empty: " 205 "did you forget to add a sc_module_name parameter to " 206 "your module constructor?", nullptr); 207 } 208 return _new_module; 209} 210 211Module * 212newModule() 213{ 214 return _new_module; 215} 216 217std::list<Module *> allModules; 218 219} // namespace sc_gem5 220