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/port.hh" 31 32#include "base/logging.hh" 33#include "systemc/core/process.hh" 34#include "systemc/core/sensitivity.hh" 35#include "systemc/ext/channel/messages.hh" 36#include "systemc/ext/channel/sc_signal_in_if.hh" 37 38namespace sc_gem5 39{ 40 41void 42Port::finalizePort(StaticSensitivityPort *port) 43{ 44 for (int i = 0; i < size(); i++) 45 port->addEvent(&getInterface(i)->default_event()); 46} 47 48void 49Port::finalizeFinder(StaticSensitivityFinder *finder) 50{ 51 for (int i = 0; i < size(); i++) 52 finder->addEvent(&finder->find(getInterface(i))); 53} 54 55void 56Port::finalizeReset(Reset *reset) 57{ 58 assert(size() <= 1); 59 if (size()) { 60 auto iface = 61 dynamic_cast<sc_core::sc_signal_in_if<bool> *>(getInterface(0)); 62 assert(iface); 63 if (!reset->install(iface)) 64 delete reset; 65 } 66} 67 68void 69Port::sensitive(StaticSensitivityPort *port) 70{ 71 if (finalized) 72 finalizePort(port); 73 else 74 sensitivities.push_back(new Sensitivity(port)); 75} 76 77void 78Port::sensitive(StaticSensitivityFinder *finder) 79{ 80 if (finalized) 81 finalizeFinder(finder); 82 else 83 sensitivities.push_back(new Sensitivity(finder)); 84} 85 86void 87Port::addReset(Reset *reset) 88{ 89 if (finalized) 90 finalizeReset(reset); 91 else 92 resets.push_back(reset); 93} 94 95void 96Port::finalize() 97{ 98 if (finalized) 99 return; 100 finalized = true; 101 102 for (auto &b: bindings) { 103 if (b->interface) { 104 addInterface(b->interface); 105 } else { 106 b->port->_gem5Port->finalize(); 107 addInterfaces(b->port); 108 } 109 delete b; 110 } 111 112 bindings.clear(); 113 114 for (auto &s: sensitivities) { 115 if (s->port) 116 finalizePort(s->port); 117 else 118 finalizeFinder(s->finder); 119 delete s; 120 } 121 122 sensitivities.clear(); 123 124 for (auto &r: resets) 125 finalizeReset(r); 126 127 resets.clear(); 128 129 if (size() > maxSize()) { 130 std::ostringstream ss; 131 ss << size() << " binds exceeds maximum of " << maxSize() << 132 " allowed"; 133 portBase->report_error(sc_core::SC_ID_COMPLETE_BINDING_, 134 ss.str().c_str()); 135 } 136 137 switch (portBase->_portPolicy()) { 138 case sc_core::SC_ONE_OR_MORE_BOUND: 139 if (size() == 0) 140 portBase->report_error(sc_core::SC_ID_COMPLETE_BINDING_, 141 "port not bound"); 142 break; 143 case sc_core::SC_ALL_BOUND: 144 if (size() < maxSize() || size() < 1) { 145 std::stringstream ss; 146 ss << size() << " actual binds is less than required " << 147 maxSize(); 148 portBase->report_error(sc_core::SC_ID_COMPLETE_BINDING_, 149 ss.str().c_str()); 150 } 151 break; 152 case sc_core::SC_ZERO_OR_MORE_BOUND: 153 break; 154 default: 155 panic("Unrecognized port policy %d.", portBase->_portPolicy()); 156 } 157} 158 159void 160Port::regPort() 161{ 162 if (!regPortNeeded) 163 return; 164 165 for (int i = 0; i < size(); i++) 166 getInterface(i)->register_port(*portBase, portBase->_ifTypeName()); 167} 168 169std::list<Port *> allPorts; 170 171} // namespace sc_gem5 172