port.hh revision 13319
113207Sgabeblack@google.com/*
213207Sgabeblack@google.com * Copyright 2018 Google, Inc.
313207Sgabeblack@google.com *
413207Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
513207Sgabeblack@google.com * modification, are permitted provided that the following conditions are
613207Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
713207Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
813207Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
913207Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1013207Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1113207Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1213207Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1313207Sgabeblack@google.com * this software without specific prior written permission.
1413207Sgabeblack@google.com *
1513207Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1613207Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1713207Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1813207Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1913207Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2013207Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2113207Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2213207Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2313207Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2413207Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2513207Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2613207Sgabeblack@google.com *
2713207Sgabeblack@google.com * Authors: Gabe Black
2813207Sgabeblack@google.com */
2913207Sgabeblack@google.com
3013207Sgabeblack@google.com#ifndef __SYSTEMC_CORE_PORT_HH__
3113207Sgabeblack@google.com#define __SYSTEMC_CORE_PORT_HH__
3213207Sgabeblack@google.com
3313207Sgabeblack@google.com#include <list>
3413273Sgabeblack@google.com#include <typeinfo>
3513207Sgabeblack@google.com#include <vector>
3613207Sgabeblack@google.com
3713239Sgabeblack@google.com#include "base/cprintf.hh"
3813207Sgabeblack@google.com#include "systemc/ext/core/sc_interface.hh"
3913207Sgabeblack@google.com#include "systemc/ext/core/sc_port.hh"
4013207Sgabeblack@google.com
4113207Sgabeblack@google.comnamespace sc_gem5
4213207Sgabeblack@google.com{
4313207Sgabeblack@google.com
4413207Sgabeblack@google.comclass StaticSensitivityPort;
4513207Sgabeblack@google.comclass StaticSensitivityFinder;
4613288Sgabeblack@google.comclass Reset;
4713207Sgabeblack@google.com
4813207Sgabeblack@google.comclass Port;
4913207Sgabeblack@google.com
5013207Sgabeblack@google.comextern std::list<Port *> allPorts;
5113207Sgabeblack@google.com
5213207Sgabeblack@google.comclass Port
5313207Sgabeblack@google.com{
5413207Sgabeblack@google.com  private:
5513207Sgabeblack@google.com    ::sc_core::sc_port_base *portBase;
5613207Sgabeblack@google.com
5713207Sgabeblack@google.com    bool finalized;
5813207Sgabeblack@google.com    int _maxSize;
5913207Sgabeblack@google.com    int _size;
6013207Sgabeblack@google.com
6113273Sgabeblack@google.com    bool regPortNeeded;
6213273Sgabeblack@google.com
6313207Sgabeblack@google.com    void finalizePort(StaticSensitivityPort *port);
6413207Sgabeblack@google.com    void finalizeFinder(StaticSensitivityFinder *finder);
6513288Sgabeblack@google.com    void finalizeReset(Reset *reset);
6613207Sgabeblack@google.com
6713207Sgabeblack@google.com    void
6813239Sgabeblack@google.com    addInterface(::sc_core::sc_interface *iface)
6913207Sgabeblack@google.com    {
7013239Sgabeblack@google.com        for (int i = 0; i < _size; i++) {
7113239Sgabeblack@google.com            if (getInterface(i) == iface) {
7213239Sgabeblack@google.com                std::string msg =
7313239Sgabeblack@google.com                    csprintf("interface already bound to port: port '%s' (%s)",
7413239Sgabeblack@google.com                        portBase->name(), portBase->kind());
7513239Sgabeblack@google.com                SC_REPORT_ERROR("(E107) bind interface to port failed",
7613239Sgabeblack@google.com                        msg.c_str());
7713239Sgabeblack@google.com            }
7813239Sgabeblack@google.com        }
7913207Sgabeblack@google.com        _size++;
8013239Sgabeblack@google.com        portBase->_gem5AddInterface(iface);
8113207Sgabeblack@google.com    }
8213207Sgabeblack@google.com
8313207Sgabeblack@google.com    void
8413207Sgabeblack@google.com    addInterfaces(::sc_core::sc_port_base *pb)
8513207Sgabeblack@google.com    {
8613273Sgabeblack@google.com        // Only the ports farthest from the interfaces call register_port.
8713273Sgabeblack@google.com        pb->_gem5Port->regPortNeeded = false;
8813207Sgabeblack@google.com        for (int i = 0; i < pb->size(); i++)
8913207Sgabeblack@google.com            addInterface(pb->_gem5Interface(i));
9013207Sgabeblack@google.com    }
9113207Sgabeblack@google.com
9213207Sgabeblack@google.com    ::sc_core::sc_interface *
9313207Sgabeblack@google.com    getInterface(int i)
9413207Sgabeblack@google.com    {
9513207Sgabeblack@google.com        return portBase->_gem5Interface(i);
9613207Sgabeblack@google.com    }
9713207Sgabeblack@google.com
9813207Sgabeblack@google.com    struct Binding
9913207Sgabeblack@google.com    {
10013207Sgabeblack@google.com        explicit Binding(::sc_core::sc_interface *interface) :
10113207Sgabeblack@google.com            interface(interface), port(nullptr)
10213207Sgabeblack@google.com        {}
10313207Sgabeblack@google.com
10413207Sgabeblack@google.com        explicit Binding(::sc_core::sc_port_base *port) :
10513207Sgabeblack@google.com            interface(nullptr), port(port)
10613207Sgabeblack@google.com        {}
10713207Sgabeblack@google.com
10813207Sgabeblack@google.com        ::sc_core::sc_interface *interface;
10913207Sgabeblack@google.com        ::sc_core::sc_port_base *port;
11013207Sgabeblack@google.com    };
11113207Sgabeblack@google.com
11213207Sgabeblack@google.com    struct Sensitivity
11313207Sgabeblack@google.com    {
11413207Sgabeblack@google.com        Sensitivity(StaticSensitivityPort *port) :
11513288Sgabeblack@google.com            port(port), finder(nullptr)
11613207Sgabeblack@google.com        {}
11713207Sgabeblack@google.com
11813207Sgabeblack@google.com        Sensitivity(StaticSensitivityFinder *finder) :
11913288Sgabeblack@google.com            port(nullptr), finder(finder)
12013207Sgabeblack@google.com        {}
12113207Sgabeblack@google.com
12213207Sgabeblack@google.com        StaticSensitivityPort *port;
12313207Sgabeblack@google.com        StaticSensitivityFinder *finder;
12413207Sgabeblack@google.com    };
12513207Sgabeblack@google.com
12613207Sgabeblack@google.com    std::vector<Binding *> bindings;
12713207Sgabeblack@google.com    std::vector<Sensitivity *> sensitivities;
12813288Sgabeblack@google.com    std::vector<Reset *> resets;
12913207Sgabeblack@google.com
13013207Sgabeblack@google.com  public:
13113207Sgabeblack@google.com    static Port *
13213207Sgabeblack@google.com    fromPort(const ::sc_core::sc_port_base *pb)
13313207Sgabeblack@google.com    {
13413207Sgabeblack@google.com        return pb->_gem5Port;
13513207Sgabeblack@google.com    }
13613207Sgabeblack@google.com
13713207Sgabeblack@google.com    ::sc_core::sc_port_base *sc_port_base() { return portBase; }
13813207Sgabeblack@google.com
13913207Sgabeblack@google.com    Port(::sc_core::sc_port_base *port_base, int max) :
14013273Sgabeblack@google.com        portBase(port_base), finalized(false), _maxSize(max), _size(0),
14113273Sgabeblack@google.com        regPortNeeded(true)
14213207Sgabeblack@google.com    {
14313207Sgabeblack@google.com        allPorts.push_front(this);
14413207Sgabeblack@google.com    }
14513207Sgabeblack@google.com
14613282Sgabeblack@google.com    ~Port() { allPorts.remove(this); }
14713282Sgabeblack@google.com
14813207Sgabeblack@google.com    void
14913207Sgabeblack@google.com    bind(::sc_core::sc_interface *interface)
15013207Sgabeblack@google.com    {
15113270Sgabeblack@google.com        if (bindings.empty())
15213270Sgabeblack@google.com            addInterface(interface);
15313270Sgabeblack@google.com        else
15413270Sgabeblack@google.com            bindings.push_back(new Binding(interface));
15513207Sgabeblack@google.com    }
15613207Sgabeblack@google.com
15713207Sgabeblack@google.com    void
15813207Sgabeblack@google.com    bind(::sc_core::sc_port_base *port)
15913207Sgabeblack@google.com    {
16013207Sgabeblack@google.com        bindings.push_back(new Binding(port));
16113207Sgabeblack@google.com    }
16213207Sgabeblack@google.com
16313207Sgabeblack@google.com    void sensitive(StaticSensitivityPort *port);
16413207Sgabeblack@google.com    void sensitive(StaticSensitivityFinder *finder);
16513288Sgabeblack@google.com    void addReset(Reset *reset);
16613207Sgabeblack@google.com
16713207Sgabeblack@google.com    void finalize();
16813273Sgabeblack@google.com    void regPort();
16913207Sgabeblack@google.com
17013207Sgabeblack@google.com    int size() { return _size; }
17113319Sgabeblack@google.com    int maxSize() { return _maxSize ? _maxSize : _size; }
17213207Sgabeblack@google.com};
17313207Sgabeblack@google.com
17413207Sgabeblack@google.com} // namespace sc_gem5
17513207Sgabeblack@google.com
17613207Sgabeblack@google.com#endif // __SYSTEMC_CORE_PORT_HH__
177