port.hh revision 13282
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#ifndef __SYSTEMC_CORE_PORT_HH__ 31#define __SYSTEMC_CORE_PORT_HH__ 32 33#include <list> 34#include <typeinfo> 35#include <vector> 36 37#include "base/cprintf.hh" 38#include "systemc/ext/core/sc_interface.hh" 39#include "systemc/ext/core/sc_port.hh" 40 41namespace sc_gem5 42{ 43 44class StaticSensitivityPort; 45class StaticSensitivityFinder; 46class ResetSensitivityPort; 47 48class Port; 49 50extern std::list<Port *> allPorts; 51 52class Port 53{ 54 private: 55 ::sc_core::sc_port_base *portBase; 56 57 bool finalized; 58 int _maxSize; 59 int _size; 60 61 bool regPortNeeded; 62 63 void finalizePort(StaticSensitivityPort *port); 64 void finalizeFinder(StaticSensitivityFinder *finder); 65 void finalizeReset(ResetSensitivityPort *reset); 66 67 void 68 addInterface(::sc_core::sc_interface *iface) 69 { 70 for (int i = 0; i < _size; i++) { 71 if (getInterface(i) == iface) { 72 std::string msg = 73 csprintf("interface already bound to port: port '%s' (%s)", 74 portBase->name(), portBase->kind()); 75 SC_REPORT_ERROR("(E107) bind interface to port failed", 76 msg.c_str()); 77 } 78 } 79 _size++; 80 portBase->_gem5AddInterface(iface); 81 } 82 83 void 84 addInterfaces(::sc_core::sc_port_base *pb) 85 { 86 // Only the ports farthest from the interfaces call register_port. 87 pb->_gem5Port->regPortNeeded = false; 88 for (int i = 0; i < pb->size(); i++) 89 addInterface(pb->_gem5Interface(i)); 90 } 91 92 ::sc_core::sc_interface * 93 getInterface(int i) 94 { 95 return portBase->_gem5Interface(i); 96 } 97 98 struct Binding 99 { 100 explicit Binding(::sc_core::sc_interface *interface) : 101 interface(interface), port(nullptr) 102 {} 103 104 explicit Binding(::sc_core::sc_port_base *port) : 105 interface(nullptr), port(port) 106 {} 107 108 ::sc_core::sc_interface *interface; 109 ::sc_core::sc_port_base *port; 110 }; 111 112 struct Sensitivity 113 { 114 Sensitivity(StaticSensitivityPort *port) : 115 port(port), finder(nullptr), reset(nullptr) 116 {} 117 118 Sensitivity(StaticSensitivityFinder *finder) : 119 port(nullptr), finder(finder), reset(nullptr) 120 {} 121 122 Sensitivity(ResetSensitivityPort *reset) : 123 port(nullptr), finder(nullptr), reset(reset) 124 {} 125 126 StaticSensitivityPort *port; 127 StaticSensitivityFinder *finder; 128 ResetSensitivityPort *reset; 129 }; 130 131 std::vector<Binding *> bindings; 132 std::vector<Sensitivity *> sensitivities; 133 134 public: 135 static Port * 136 fromPort(const ::sc_core::sc_port_base *pb) 137 { 138 return pb->_gem5Port; 139 } 140 141 ::sc_core::sc_port_base *sc_port_base() { return portBase; } 142 143 Port(::sc_core::sc_port_base *port_base, int max) : 144 portBase(port_base), finalized(false), _maxSize(max), _size(0), 145 regPortNeeded(true) 146 { 147 allPorts.push_front(this); 148 } 149 150 ~Port() { allPorts.remove(this); } 151 152 void 153 bind(::sc_core::sc_interface *interface) 154 { 155 if (bindings.empty()) 156 addInterface(interface); 157 else 158 bindings.push_back(new Binding(interface)); 159 } 160 161 void 162 bind(::sc_core::sc_port_base *port) 163 { 164 bindings.push_back(new Binding(port)); 165 } 166 167 void sensitive(StaticSensitivityPort *port); 168 void sensitive(StaticSensitivityFinder *finder); 169 void sensitive(ResetSensitivityPort *reset); 170 171 void finalize(); 172 void regPort(); 173 174 int size() { return _size; } 175 int maxSize() { return _maxSize; } 176}; 177 178} // namespace sc_gem5 179 180#endif // __SYSTEMC_CORE_PORT_HH__ 181