sc_port_wrapper.hh revision 14126
114126Schunchenhsu@google.com/* 214126Schunchenhsu@google.com * Copyright 2019 Google LLC. 314126Schunchenhsu@google.com * 414126Schunchenhsu@google.com * Redistribution and use in source and binary forms, with or without 514126Schunchenhsu@google.com * modification, are permitted provided that the following conditions are 614126Schunchenhsu@google.com * met: redistributions of source code must retain the above copyright 714126Schunchenhsu@google.com * notice, this list of conditions and the following disclaimer; 814126Schunchenhsu@google.com * redistributions in binary form must reproduce the above copyright 914126Schunchenhsu@google.com * notice, this list of conditions and the following disclaimer in the 1014126Schunchenhsu@google.com * documentation and/or other materials provided with the distribution; 1114126Schunchenhsu@google.com * neither the name of the copyright holders nor the names of its 1214126Schunchenhsu@google.com * contributors may be used to endorse or promote products derived from 1314126Schunchenhsu@google.com * this software without specific prior written permission. 1414126Schunchenhsu@google.com * 1514126Schunchenhsu@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1614126Schunchenhsu@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1714126Schunchenhsu@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1814126Schunchenhsu@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1914126Schunchenhsu@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2014126Schunchenhsu@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2114126Schunchenhsu@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2214126Schunchenhsu@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2314126Schunchenhsu@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2414126Schunchenhsu@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2514126Schunchenhsu@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2614126Schunchenhsu@google.com * 2714126Schunchenhsu@google.com * Authors: Chun-Chen TK Hsu 2814126Schunchenhsu@google.com */ 2914126Schunchenhsu@google.com 3014126Schunchenhsu@google.com#ifndef __SYSTEMC_SC_PORT_WRAPPER_HH__ 3114126Schunchenhsu@google.com#define __SYSTEMC_SC_PORT_WRAPPER_HH__ 3214126Schunchenhsu@google.com 3314126Schunchenhsu@google.com#include <string> 3414126Schunchenhsu@google.com#include <type_traits> 3514126Schunchenhsu@google.com 3614126Schunchenhsu@google.com#include "base/logging.hh" 3714126Schunchenhsu@google.com#include "sim/port.hh" 3814126Schunchenhsu@google.com#include "systemc/ext/core/sc_export.hh" 3914126Schunchenhsu@google.com#include "systemc/ext/core/sc_interface.hh" 4014126Schunchenhsu@google.com#include "systemc/ext/core/sc_port.hh" 4114126Schunchenhsu@google.com 4214126Schunchenhsu@google.comnamespace sc_gem5 4314126Schunchenhsu@google.com{ 4414126Schunchenhsu@google.com 4514126Schunchenhsu@google.com// Forward declaration 4614126Schunchenhsu@google.comtemplate <typename IF> 4714126Schunchenhsu@google.comclass ScPortWrapper; 4814126Schunchenhsu@google.comtemplate <typename IF> 4914126Schunchenhsu@google.comclass ScInterfaceWrapper; 5014126Schunchenhsu@google.comtemplate <typename IF> 5114126Schunchenhsu@google.comclass ScExportWrapper; 5214126Schunchenhsu@google.com 5314126Schunchenhsu@google.comtemplate <typename IF> 5414126Schunchenhsu@google.comclass ScPortWrapper : public ::Port 5514126Schunchenhsu@google.com{ 5614126Schunchenhsu@google.com public: 5714126Schunchenhsu@google.com using ScPort = sc_core::sc_port_b<IF>; 5814126Schunchenhsu@google.com 5914126Schunchenhsu@google.com ScPortWrapper(ScPort& p, const std::string& name, PortID id) 6014126Schunchenhsu@google.com : Port(name, id), port_(p) 6114126Schunchenhsu@google.com {} 6214126Schunchenhsu@google.com 6314126Schunchenhsu@google.com ScPort& 6414126Schunchenhsu@google.com port() 6514126Schunchenhsu@google.com { 6614126Schunchenhsu@google.com return port_; 6714126Schunchenhsu@google.com } 6814126Schunchenhsu@google.com 6914126Schunchenhsu@google.com void 7014126Schunchenhsu@google.com unbind() override 7114126Schunchenhsu@google.com { 7214126Schunchenhsu@google.com panic("sc_port can't be unbound."); 7314126Schunchenhsu@google.com } 7414126Schunchenhsu@google.com 7514126Schunchenhsu@google.com void 7614126Schunchenhsu@google.com bind(::Port& peer) override 7714126Schunchenhsu@google.com { 7814126Schunchenhsu@google.com // Try ScPortWrapper or ScInterfaceWrapper 7914126Schunchenhsu@google.com if (auto* beer = dynamic_cast<ScPortWrapper<IF>*>(&peer)) { 8014126Schunchenhsu@google.com port_.bind(beer->port()); 8114126Schunchenhsu@google.com } else if (auto* iface = 8214126Schunchenhsu@google.com dynamic_cast<ScInterfaceWrapper<IF>*>(&peer)) { 8314126Schunchenhsu@google.com port_.bind(iface->interface()); 8414126Schunchenhsu@google.com } else { 8514126Schunchenhsu@google.com fatal("Attempt to bind sc_port %s to incompatible port %s.", 8614126Schunchenhsu@google.com name(), peer.name()); 8714126Schunchenhsu@google.com } 8814126Schunchenhsu@google.com } 8914126Schunchenhsu@google.com 9014126Schunchenhsu@google.com private: 9114126Schunchenhsu@google.com ScPort& port_; 9214126Schunchenhsu@google.com}; 9314126Schunchenhsu@google.com 9414126Schunchenhsu@google.comtemplate <typename IF> 9514126Schunchenhsu@google.comclass ScInterfaceWrapper : public ::Port 9614126Schunchenhsu@google.com{ 9714126Schunchenhsu@google.com public: 9814126Schunchenhsu@google.com ScInterfaceWrapper(IF& i, const std::string name, PortID id) 9914126Schunchenhsu@google.com : Port(name, id), iface_(i) 10014126Schunchenhsu@google.com {} 10114126Schunchenhsu@google.com 10214126Schunchenhsu@google.com IF& 10314126Schunchenhsu@google.com interface() 10414126Schunchenhsu@google.com { 10514126Schunchenhsu@google.com return iface_; 10614126Schunchenhsu@google.com } 10714126Schunchenhsu@google.com 10814126Schunchenhsu@google.com void 10914126Schunchenhsu@google.com unbind() override 11014126Schunchenhsu@google.com { 11114126Schunchenhsu@google.com panic("sc_interface can't be unbound."); 11214126Schunchenhsu@google.com } 11314126Schunchenhsu@google.com 11414126Schunchenhsu@google.com void 11514126Schunchenhsu@google.com bind(::Port& peer) override 11614126Schunchenhsu@google.com { 11714126Schunchenhsu@google.com // fatal error if peer is neither ScPortWrapper nor ScExportWrapper 11814126Schunchenhsu@google.com fatal_if(!dynamic_cast<ScPortWrapper<IF>*>(&peer) && 11914126Schunchenhsu@google.com !dynamic_cast<ScExportWrapper<IF>*>(&peer), 12014126Schunchenhsu@google.com "Attempt to bind sc_interface %s to incompatible port %s.", 12114126Schunchenhsu@google.com name(), peer.name()); 12214126Schunchenhsu@google.com 12314126Schunchenhsu@google.com // Don't bind to peer otherwise we may have error messages saying that 12414126Schunchenhsu@google.com // this interface has already be bound since the peer may already did 12514126Schunchenhsu@google.com // that. Just let sc_port or sc_export do the binding 12614126Schunchenhsu@google.com } 12714126Schunchenhsu@google.com 12814126Schunchenhsu@google.com private: 12914126Schunchenhsu@google.com IF& iface_; 13014126Schunchenhsu@google.com}; 13114126Schunchenhsu@google.com 13214126Schunchenhsu@google.comtemplate <typename IF> 13314126Schunchenhsu@google.comclass ScExportWrapper : public ::Port 13414126Schunchenhsu@google.com{ 13514126Schunchenhsu@google.com public: 13614126Schunchenhsu@google.com using ScExport = sc_core::sc_export<IF>; 13714126Schunchenhsu@google.com 13814126Schunchenhsu@google.com ScExportWrapper(ScExport& p, const std::string& name, PortID id) 13914126Schunchenhsu@google.com : Port(name, id), port_(p) 14014126Schunchenhsu@google.com {} 14114126Schunchenhsu@google.com 14214126Schunchenhsu@google.com ScExport& 14314126Schunchenhsu@google.com port() 14414126Schunchenhsu@google.com { 14514126Schunchenhsu@google.com return port_; 14614126Schunchenhsu@google.com } 14714126Schunchenhsu@google.com 14814126Schunchenhsu@google.com void 14914126Schunchenhsu@google.com unbind() override 15014126Schunchenhsu@google.com { 15114126Schunchenhsu@google.com panic("sc_export cannot be unbound."); 15214126Schunchenhsu@google.com } 15314126Schunchenhsu@google.com 15414126Schunchenhsu@google.com void 15514126Schunchenhsu@google.com bind(::Port& peer) override 15614126Schunchenhsu@google.com { 15714126Schunchenhsu@google.com auto* iface = dynamic_cast<ScInterfaceWrapper<IF>*>(&peer); 15814126Schunchenhsu@google.com fatal_if(!iface, 15914126Schunchenhsu@google.com "Attempt to bind sc_export %s to incompatible port %s.", 16014126Schunchenhsu@google.com name(), peer.name()); 16114126Schunchenhsu@google.com 16214126Schunchenhsu@google.com port_.bind(iface->interface()); 16314126Schunchenhsu@google.com } 16414126Schunchenhsu@google.com 16514126Schunchenhsu@google.com private: 16614126Schunchenhsu@google.com ScExport& port_; 16714126Schunchenhsu@google.com}; 16814126Schunchenhsu@google.com 16914126Schunchenhsu@google.com} // namespace sc_gem5 17014126Schunchenhsu@google.com 17114126Schunchenhsu@google.com#endif // __SYSTEMC_SC_PORT_WRAPPER_HH__ 172