| /* | |
| * Copyright 2018 Google, Inc. | |
| * | |
| * 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. | |
| * | |
| * Authors: Gabe Black | |
| */ | |
| #include "systemc/core/port.hh" | |
| #include "base/logging.hh" | |
| #include "systemc/core/process.hh" | |
| #include "systemc/core/sensitivity.hh" | |
| #include "systemc/ext/channel/messages.hh" | |
| #include "systemc/ext/channel/sc_signal_in_if.hh" | |
| namespace sc_gem5 | |
| { | |
| void | |
| Port::finalizePort(StaticSensitivityPort *port) | |
| { | |
| for (int i = 0; i < size(); i++) | |
| port->addEvent(&getInterface(i)->default_event()); | |
| } | |
| void | |
| Port::finalizeFinder(StaticSensitivityFinder *finder) | |
| { | |
| for (int i = 0; i < size(); i++) | |
| finder->addEvent(&finder->find(getInterface(i))); | |
| } | |
| void | |
| Port::finalizeReset(Reset *reset) | |
| { | |
| assert(size() <= 1); | |
| if (size()) { | |
| auto iface = | |
| dynamic_cast<sc_core::sc_signal_in_if<bool> *>(getInterface(0)); | |
| assert(iface); | |
| if (!reset->install(iface)) | |
| delete reset; | |
| } | |
| } | |
| void | |
| Port::sensitive(StaticSensitivityPort *port) | |
| { | |
| if (finalized) | |
| finalizePort(port); | |
| else | |
| sensitivities.push_back(new Sensitivity(port)); | |
| } | |
| void | |
| Port::sensitive(StaticSensitivityFinder *finder) | |
| { | |
| if (finalized) | |
| finalizeFinder(finder); | |
| else | |
| sensitivities.push_back(new Sensitivity(finder)); | |
| } | |
| void | |
| Port::addReset(Reset *reset) | |
| { | |
| if (finalized) | |
| finalizeReset(reset); | |
| else | |
| resets.push_back(reset); | |
| } | |
| void | |
| Port::finalize() | |
| { | |
| if (finalized) | |
| return; | |
| finalized = true; | |
| for (auto &b: bindings) { | |
| if (b->interface) { | |
| addInterface(b->interface); | |
| } else { | |
| b->port->_gem5Port->finalize(); | |
| addInterfaces(b->port); | |
| } | |
| delete b; | |
| } | |
| bindings.clear(); | |
| for (auto &s: sensitivities) { | |
| if (s->port) | |
| finalizePort(s->port); | |
| else | |
| finalizeFinder(s->finder); | |
| delete s; | |
| } | |
| sensitivities.clear(); | |
| for (auto &r: resets) | |
| finalizeReset(r); | |
| resets.clear(); | |
| if (size() > maxSize()) { | |
| std::ostringstream ss; | |
| ss << size() << " binds exceeds maximum of " << maxSize() << | |
| " allowed"; | |
| portBase->report_error(sc_core::SC_ID_COMPLETE_BINDING_, | |
| ss.str().c_str()); | |
| } | |
| switch (portBase->_portPolicy()) { | |
| case sc_core::SC_ONE_OR_MORE_BOUND: | |
| if (size() == 0) | |
| portBase->report_error(sc_core::SC_ID_COMPLETE_BINDING_, | |
| "port not bound"); | |
| break; | |
| case sc_core::SC_ALL_BOUND: | |
| if (size() < maxSize() || size() < 1) { | |
| std::stringstream ss; | |
| ss << size() << " actual binds is less than required " << | |
| maxSize(); | |
| portBase->report_error(sc_core::SC_ID_COMPLETE_BINDING_, | |
| ss.str().c_str()); | |
| } | |
| break; | |
| case sc_core::SC_ZERO_OR_MORE_BOUND: | |
| break; | |
| default: | |
| panic("Unrecognized port policy %d.", portBase->_portPolicy()); | |
| } | |
| } | |
| void | |
| Port::regPort() | |
| { | |
| if (!regPortNeeded) | |
| return; | |
| for (int i = 0; i < size(); i++) | |
| getInterface(i)->register_port(*portBase, portBase->_ifTypeName()); | |
| } | |
| std::list<Port *> allPorts; | |
| } // namespace sc_gem5 |