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 } 8814189Sgabeblack@google.com Port::bind(peer); 8914126Schunchenhsu@google.com } 9014126Schunchenhsu@google.com 9114126Schunchenhsu@google.com private: 9214126Schunchenhsu@google.com ScPort& port_; 9314126Schunchenhsu@google.com}; 9414126Schunchenhsu@google.com 9514126Schunchenhsu@google.comtemplate <typename IF> 9614126Schunchenhsu@google.comclass ScInterfaceWrapper : public ::Port 9714126Schunchenhsu@google.com{ 9814126Schunchenhsu@google.com public: 9914126Schunchenhsu@google.com ScInterfaceWrapper(IF& i, const std::string name, PortID id) 10014126Schunchenhsu@google.com : Port(name, id), iface_(i) 10114126Schunchenhsu@google.com {} 10214126Schunchenhsu@google.com 10314126Schunchenhsu@google.com IF& 10414126Schunchenhsu@google.com interface() 10514126Schunchenhsu@google.com { 10614126Schunchenhsu@google.com return iface_; 10714126Schunchenhsu@google.com } 10814126Schunchenhsu@google.com 10914126Schunchenhsu@google.com void 11014126Schunchenhsu@google.com unbind() override 11114126Schunchenhsu@google.com { 11214126Schunchenhsu@google.com panic("sc_interface can't be unbound."); 11314126Schunchenhsu@google.com } 11414126Schunchenhsu@google.com 11514126Schunchenhsu@google.com void 11614126Schunchenhsu@google.com bind(::Port& peer) override 11714126Schunchenhsu@google.com { 11814126Schunchenhsu@google.com // fatal error if peer is neither ScPortWrapper nor ScExportWrapper 11914126Schunchenhsu@google.com fatal_if(!dynamic_cast<ScPortWrapper<IF>*>(&peer) && 12014126Schunchenhsu@google.com !dynamic_cast<ScExportWrapper<IF>*>(&peer), 12114126Schunchenhsu@google.com "Attempt to bind sc_interface %s to incompatible port %s.", 12214126Schunchenhsu@google.com name(), peer.name()); 12314126Schunchenhsu@google.com 12414126Schunchenhsu@google.com // Don't bind to peer otherwise we may have error messages saying that 12514126Schunchenhsu@google.com // this interface has already be bound since the peer may already did 12614126Schunchenhsu@google.com // that. Just let sc_port or sc_export do the binding 12714189Sgabeblack@google.com Port::bind(peer); 12814126Schunchenhsu@google.com } 12914126Schunchenhsu@google.com 13014126Schunchenhsu@google.com private: 13114126Schunchenhsu@google.com IF& iface_; 13214126Schunchenhsu@google.com}; 13314126Schunchenhsu@google.com 13414126Schunchenhsu@google.comtemplate <typename IF> 13514126Schunchenhsu@google.comclass ScExportWrapper : public ::Port 13614126Schunchenhsu@google.com{ 13714126Schunchenhsu@google.com public: 13814126Schunchenhsu@google.com using ScExport = sc_core::sc_export<IF>; 13914126Schunchenhsu@google.com 14014126Schunchenhsu@google.com ScExportWrapper(ScExport& p, const std::string& name, PortID id) 14114126Schunchenhsu@google.com : Port(name, id), port_(p) 14214126Schunchenhsu@google.com {} 14314126Schunchenhsu@google.com 14414126Schunchenhsu@google.com ScExport& 14514126Schunchenhsu@google.com port() 14614126Schunchenhsu@google.com { 14714126Schunchenhsu@google.com return port_; 14814126Schunchenhsu@google.com } 14914126Schunchenhsu@google.com 15014126Schunchenhsu@google.com void 15114126Schunchenhsu@google.com unbind() override 15214126Schunchenhsu@google.com { 15314126Schunchenhsu@google.com panic("sc_export cannot be unbound."); 15414126Schunchenhsu@google.com } 15514126Schunchenhsu@google.com 15614126Schunchenhsu@google.com void 15714126Schunchenhsu@google.com bind(::Port& peer) override 15814126Schunchenhsu@google.com { 15914126Schunchenhsu@google.com auto* iface = dynamic_cast<ScInterfaceWrapper<IF>*>(&peer); 16014126Schunchenhsu@google.com fatal_if(!iface, 16114126Schunchenhsu@google.com "Attempt to bind sc_export %s to incompatible port %s.", 16214126Schunchenhsu@google.com name(), peer.name()); 16314126Schunchenhsu@google.com 16414126Schunchenhsu@google.com port_.bind(iface->interface()); 16514189Sgabeblack@google.com Port::bind(peer); 16614126Schunchenhsu@google.com } 16714126Schunchenhsu@google.com 16814126Schunchenhsu@google.com private: 16914126Schunchenhsu@google.com ScExport& port_; 17014126Schunchenhsu@google.com}; 17114126Schunchenhsu@google.com 17214126Schunchenhsu@google.com} // namespace sc_gem5 17314126Schunchenhsu@google.com 17414126Schunchenhsu@google.com#endif // __SYSTEMC_SC_PORT_WRAPPER_HH__ 175