port.hh revision 13282
12292SN/A/*
22329SN/A * Copyright 2018 Google, Inc.
32292SN/A *
42292SN/A * Redistribution and use in source and binary forms, with or without
52292SN/A * modification, are permitted provided that the following conditions are
62292SN/A * met: redistributions of source code must retain the above copyright
72292SN/A * notice, this list of conditions and the following disclaimer;
82292SN/A * redistributions in binary form must reproduce the above copyright
92292SN/A * notice, this list of conditions and the following disclaimer in the
102292SN/A * documentation and/or other materials provided with the distribution;
112292SN/A * neither the name of the copyright holders nor the names of its
122292SN/A * contributors may be used to endorse or promote products derived from
132292SN/A * this software without specific prior written permission.
142292SN/A *
152292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
162292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
172292SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
182292SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
192292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
202292SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
212292SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
222292SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
232292SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
242292SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
252292SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
262292SN/A *
272689Sktlim@umich.edu * Authors: Gabe Black
282689Sktlim@umich.edu */
292689Sktlim@umich.edu
302292SN/A#ifndef __SYSTEMC_CORE_PORT_HH__
312292SN/A#define __SYSTEMC_CORE_PORT_HH__
322292SN/A
332292SN/A#include <list>
342292SN/A#include <typeinfo>
352329SN/A#include <vector>
364395Ssaidi@eecs.umich.edu
372292SN/A#include "base/cprintf.hh"
382292SN/A#include "systemc/ext/core/sc_interface.hh"
392292SN/A#include "systemc/ext/core/sc_port.hh"
408591Sgblack@eecs.umich.edu
418506Sgblack@eecs.umich.edunamespace sc_gem5
423326Sktlim@umich.edu{
438481Sgblack@eecs.umich.edu
448229Snate@binkert.orgclass StaticSensitivityPort;
456658Snate@binkert.orgclass StaticSensitivityFinder;
462292SN/Aclass ResetSensitivityPort;
478230Snate@binkert.org
488232Snate@binkert.orgclass Port;
493348Sbinkertn@umich.edu
502669Sktlim@umich.eduextern std::list<Port *> allPorts;
518817Sgblack@eecs.umich.edu
522292SN/Aclass Port
538737Skoansin.tan@gmail.com{
545529Snate@binkert.org  private:
552292SN/A    ::sc_core::sc_port_base *portBase;
562329SN/A
572329SN/A    bool finalized;
582329SN/A    int _maxSize;
592329SN/A    int _size;
602329SN/A
612329SN/A    bool regPortNeeded;
622329SN/A
632329SN/A    void finalizePort(StaticSensitivityPort *port);
642329SN/A    void finalizeFinder(StaticSensitivityFinder *finder);
652329SN/A    void finalizeReset(ResetSensitivityPort *reset);
662292SN/A
672292SN/A    void
682292SN/A    addInterface(::sc_core::sc_interface *iface)
692292SN/A    {
702733Sktlim@umich.edu        for (int i = 0; i < _size; i++) {
712292SN/A            if (getInterface(i) == iface) {
722292SN/A                std::string msg =
732907Sktlim@umich.edu                    csprintf("interface already bound to port: port '%s' (%s)",
742292SN/A                        portBase->name(), portBase->kind());
752292SN/A                SC_REPORT_ERROR("(E107) bind interface to port failed",
762292SN/A                        msg.c_str());
772292SN/A            }
782292SN/A        }
792292SN/A        _size++;
802292SN/A        portBase->_gem5AddInterface(iface);
815529Snate@binkert.org    }
825529Snate@binkert.org
835529Snate@binkert.org    void
842292SN/A    addInterfaces(::sc_core::sc_port_base *pb)
852292SN/A    {
862292SN/A        // Only the ports farthest from the interfaces call register_port.
872292SN/A        pb->_gem5Port->regPortNeeded = false;
882727Sktlim@umich.edu        for (int i = 0; i < pb->size(); i++)
892727Sktlim@umich.edu            addInterface(pb->_gem5Interface(i));
902727Sktlim@umich.edu    }
912907Sktlim@umich.edu
928922Swilliam.wang@arm.com    ::sc_core::sc_interface *
932907Sktlim@umich.edu    getInterface(int i)
942348SN/A    {
952307SN/A        return portBase->_gem5Interface(i);
962307SN/A    }
972348SN/A
982307SN/A    struct Binding
992307SN/A    {
1002348SN/A        explicit Binding(::sc_core::sc_interface *interface) :
1012307SN/A            interface(interface), port(nullptr)
1022307SN/A        {}
1032292SN/A
1042292SN/A        explicit Binding(::sc_core::sc_port_base *port) :
1052292SN/A            interface(nullptr), port(port)
1062292SN/A        {}
1072292SN/A
1082292SN/A        ::sc_core::sc_interface *interface;
1092292SN/A        ::sc_core::sc_port_base *port;
1102292SN/A    };
1112292SN/A
1122292SN/A    struct Sensitivity
1132292SN/A    {
1142292SN/A        Sensitivity(StaticSensitivityPort *port) :
1152292SN/A            port(port), finder(nullptr), reset(nullptr)
1162292SN/A        {}
1178545Ssaidi@eecs.umich.edu
1188545Ssaidi@eecs.umich.edu        Sensitivity(StaticSensitivityFinder *finder) :
1198545Ssaidi@eecs.umich.edu            port(nullptr), finder(finder), reset(nullptr)
1208199SAli.Saidi@ARM.com        {}
1218199SAli.Saidi@ARM.com
1228199SAli.Saidi@ARM.com        Sensitivity(ResetSensitivityPort *reset) :
1238199SAli.Saidi@ARM.com            port(nullptr), finder(nullptr), reset(reset)
1248199SAli.Saidi@ARM.com        {}
1258545Ssaidi@eecs.umich.edu
1268545Ssaidi@eecs.umich.edu        StaticSensitivityPort *port;
1278545Ssaidi@eecs.umich.edu        StaticSensitivityFinder *finder;
1288545Ssaidi@eecs.umich.edu        ResetSensitivityPort *reset;
1298545Ssaidi@eecs.umich.edu    };
1308545Ssaidi@eecs.umich.edu
1312292SN/A    std::vector<Binding *> bindings;
1322292SN/A    std::vector<Sensitivity *> sensitivities;
1332292SN/A
1342329SN/A  public:
1352292SN/A    static Port *
1362292SN/A    fromPort(const ::sc_core::sc_port_base *pb)
1372292SN/A    {
1382292SN/A        return pb->_gem5Port;
1392292SN/A    }
1402292SN/A
1412292SN/A    ::sc_core::sc_port_base *sc_port_base() { return portBase; }
1422292SN/A
1432292SN/A    Port(::sc_core::sc_port_base *port_base, int max) :
1442292SN/A        portBase(port_base), finalized(false), _maxSize(max), _size(0),
1452292SN/A        regPortNeeded(true)
1462292SN/A    {
1472292SN/A        allPorts.push_front(this);
1482292SN/A    }
1492790Sktlim@umich.edu
1502790Sktlim@umich.edu    ~Port() { allPorts.remove(this); }
1512669Sktlim@umich.edu
1522669Sktlim@umich.edu    void
1532292SN/A    bind(::sc_core::sc_interface *interface)
1542292SN/A    {
1552292SN/A        if (bindings.empty())
1562292SN/A            addInterface(interface);
1572292SN/A        else
1582292SN/A            bindings.push_back(new Binding(interface));
1592292SN/A    }
1602292SN/A
1612292SN/A    void
1622292SN/A    bind(::sc_core::sc_port_base *port)
1632292SN/A    {
1642292SN/A        bindings.push_back(new Binding(port));
1652292SN/A    }
1662292SN/A
1672292SN/A    void sensitive(StaticSensitivityPort *port);
1682292SN/A    void sensitive(StaticSensitivityFinder *finder);
1692292SN/A    void sensitive(ResetSensitivityPort *reset);
1702292SN/A
1712292SN/A    void finalize();
1722292SN/A    void regPort();
1732292SN/A
1742292SN/A    int size() { return _size; }
1752292SN/A    int maxSize() { return _maxSize; }
1762329SN/A};
1772292SN/A
1782292SN/A} // namespace sc_gem5
1792292SN/A
1802348SN/A#endif // __SYSTEMC_CORE_PORT_HH__
1812292SN/A