sc_port.hh revision 13091:81fceed26e1e
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_EXT_CORE_SC_PORT_HH__ 31#define __SYSTEMC_EXT_CORE_SC_PORT_HH__ 32 33#include <vector> 34 35#include "../utils/sc_report_handler.hh" 36#include "sc_module.hh" // for sc_gen_unique_name 37#include "sc_object.hh" 38 39namespace sc_gem5 40{ 41 42class BindInfo; 43class Module; 44class PendingSensitivityPort; 45 46}; 47 48namespace sc_core 49{ 50 51class sc_interface; 52 53enum sc_port_policy 54{ 55 SC_ONE_OR_MORE_BOUND, // Default 56 SC_ZERO_OR_MORE_BOUND, 57 SC_ALL_BOUND 58}; 59 60class sc_port_base : public sc_object 61{ 62 public: 63 sc_port_base(const char *name, int n, sc_port_policy p); 64 65 void warn_unimpl(const char *func) const; 66 67 int maxSize() const; 68 int size() const; 69 70 protected: 71 // Implementation defined, but depended on by the tests. 72 void bind(sc_interface &); 73 void bind(sc_port_base &); 74 75 friend class ::sc_gem5::Module; 76 77 // Implementation defined, but depended on by the tests. 78 virtual int vbind(sc_interface &) = 0; 79 virtual int vbind(sc_port_base &) = 0; 80 81 virtual void before_end_of_elaboration() = 0; 82 virtual void end_of_elaboration() = 0; 83 virtual void start_of_simulation() = 0; 84 virtual void end_of_simulation() = 0; 85 86 private: 87 friend class ::sc_gem5::PendingSensitivityPort; 88 friend class ::sc_gem5::Kernel; 89 90 void _gem5Finalize(); 91 92 virtual sc_interface *_gem5Interface(int n) const = 0; 93 virtual void _gem5AddInterface(sc_interface *i) = 0; 94 95 std::vector<::sc_gem5::BindInfo *> _gem5BindInfo; 96 int _maxSize; 97 int _size; 98 bool finalized; 99}; 100 101template <class IF> 102class sc_port_b : public sc_port_base 103{ 104 public: 105 void operator () (IF &i) { bind(i); } 106 void operator () (sc_port_b<IF> &p) { bind(p); } 107 108 virtual void bind(IF &i) { sc_port_base::bind(i); } 109 virtual void bind(sc_port_b<IF> &p) { sc_port_base::bind(p); } 110 111 IF * 112 operator -> () 113 { 114 sc_assert(!_interfaces.empty()); 115 return _interfaces[0]; 116 } 117 const IF * 118 operator -> () const 119 { 120 sc_assert(!_interfaces.empty()); 121 return _interfaces[0]; 122 } 123 124 IF * 125 operator [] (int n) 126 { 127 sc_assert(_interfaces.size() > n); 128 return _interfaces[n]; 129 } 130 const IF * 131 operator [] (int n) const 132 { 133 sc_assert(_interfaces.size() > n); 134 return _interfaces[n]; 135 } 136 137 sc_interface * 138 get_interface() 139 { 140 sc_assert(!_interfaces.empty()); 141 return _interfaces[0]; 142 } 143 const sc_interface * 144 get_interface() const 145 { 146 sc_assert(!_interfaces.empty()); 147 return _interfaces[0]; 148 } 149 150 protected: 151 void before_end_of_elaboration() {} 152 void end_of_elaboration() {} 153 void start_of_simulation() {} 154 void end_of_simulation() {} 155 156 explicit sc_port_b(int n, sc_port_policy p) : 157 sc_port_base(sc_gen_unique_name("port"), n, p) 158 {} 159 sc_port_b(const char *name, int n, sc_port_policy p) : 160 sc_port_base(name, n, p) 161 {} 162 virtual ~sc_port_b() {} 163 164 // Implementation defined, but depended on by the tests. 165 int 166 vbind(sc_interface &i) 167 { 168 IF *interface = dynamic_cast<IF *>(&i); 169 if (!interface) 170 return 2; 171 sc_port_base::bind(*interface); 172 return 0; 173 } 174 int 175 vbind(sc_port_base &pb) 176 { 177 sc_port_b<IF> *p = dynamic_cast<sc_port_b<IF> *>(&pb); 178 if (!p) 179 return 2; 180 sc_port_base::bind(*p); 181 return 0; 182 } 183 184 private: 185 std::vector<IF *> _interfaces; 186 187 sc_interface * 188 _gem5Interface(int n) const 189 { 190 sc_assert(_interfaces.size() > n); 191 return _interfaces[n]; 192 } 193 void 194 _gem5AddInterface(sc_interface *i) 195 { 196 IF *interface = dynamic_cast<IF *>(i); 197 sc_assert(interface); 198 _interfaces.push_back(interface); 199 } 200 201 // Disabled 202 sc_port_b() {} 203 sc_port_b(const sc_port_b<IF> &) {} 204 sc_port_b<IF> &operator = (const sc_port_b<IF> &) { return *this; } 205}; 206 207template <class IF, int N=1, sc_port_policy P=SC_ONE_OR_MORE_BOUND> 208class sc_port : public sc_port_b<IF> 209{ 210 public: 211 sc_port() : sc_port_b<IF>(N, P) {} 212 explicit sc_port(const char *name) : sc_port_b<IF>(name, N, P) {} 213 virtual ~sc_port() {} 214 215 // Deprecated binding constructors. 216 explicit sc_port(const IF &interface) : sc_port_b<IF>(N, P) 217 { 218 this->warn_unimpl(__PRETTY_FUNCTION__); 219 // Should warn that these are deprecated. See Accellera sc_port.h. 220 sc_port_b<IF>::bind(const_cast<IF &>(interface)); 221 } 222 sc_port(const char *name, const IF &interface) : sc_port_b<IF>(name, N, P) 223 { 224 this->warn_unimpl(__PRETTY_FUNCTION__); 225 // Should warn that these are deprecated. See Accellera sc_port.h. 226 sc_port_b<IF>::bind(const_cast<IF &>(interface)); 227 } 228 explicit sc_port(sc_port_b<IF> &parent) : sc_port_b<IF>(N, P) 229 { 230 this->warn_unimpl(__PRETTY_FUNCTION__); 231 // Should warn that these are deprecated. See Accellera sc_port.h. 232 sc_port_b<IF>::bind(parent); 233 } 234 sc_port(const char *name, sc_port_b<IF> &parent) : 235 sc_port_b<IF>(name, N, P) 236 { 237 this->warn_unimpl(__PRETTY_FUNCTION__); 238 // Should warn that these are deprecated. See Accellera sc_port.h. 239 sc_port_b<IF>::bind(parent); 240 } 241 explicit sc_port(sc_port<IF, N, P> &parent) : sc_port_b<IF>(N, P) 242 { 243 this->warn_unimpl(__PRETTY_FUNCTION__); 244 // Should warn that these are deprecated. See Accellera sc_port.h. 245 sc_port_b<IF>::bind(parent); 246 } 247 sc_port(const char *name, sc_port<IF, N, P> &parent) : 248 sc_port_b<IF>(name, N, P) 249 { 250 this->warn_unimpl(__PRETTY_FUNCTION__); 251 // Should warn that these are deprecated. See Accellera sc_port.h. 252 sc_port_b<IF>::bind(parent); 253 } 254 255 virtual const char *kind() const { return "sc_port"; } 256 257 private: 258 // Disabled 259 sc_port(const sc_port<IF, N, P> &) {} 260 sc_port<IF, N, P> &operator = (const sc_port<IF, N, P> &) { return *this; } 261}; 262 263} // namespace sc_core 264 265#endif //__SYSTEMC_EXT_CORE_SC_PORT_HH__ 266