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    {
7013321Sgabeblack@google.com        portBase->_gem5AddInterface(iface);
7113207Sgabeblack@google.com        _size++;
7213207Sgabeblack@google.com    }
7313207Sgabeblack@google.com
7413207Sgabeblack@google.com    void
7513207Sgabeblack@google.com    addInterfaces(::sc_core::sc_port_base *pb)
7613207Sgabeblack@google.com    {
7713273Sgabeblack@google.com        // Only the ports farthest from the interfaces call register_port.
7813273Sgabeblack@google.com        pb->_gem5Port->regPortNeeded = false;
7913207Sgabeblack@google.com        for (int i = 0; i < pb->size(); i++)
8013207Sgabeblack@google.com            addInterface(pb->_gem5Interface(i));
8113207Sgabeblack@google.com    }
8213207Sgabeblack@google.com
8313207Sgabeblack@google.com    ::sc_core::sc_interface *
8413207Sgabeblack@google.com    getInterface(int i)
8513207Sgabeblack@google.com    {
8613207Sgabeblack@google.com        return portBase->_gem5Interface(i);
8713207Sgabeblack@google.com    }
8813207Sgabeblack@google.com
8913207Sgabeblack@google.com    struct Binding
9013207Sgabeblack@google.com    {
9113207Sgabeblack@google.com        explicit Binding(::sc_core::sc_interface *interface) :
9213207Sgabeblack@google.com            interface(interface), port(nullptr)
9313207Sgabeblack@google.com        {}
9413207Sgabeblack@google.com
9513207Sgabeblack@google.com        explicit Binding(::sc_core::sc_port_base *port) :
9613207Sgabeblack@google.com            interface(nullptr), port(port)
9713207Sgabeblack@google.com        {}
9813207Sgabeblack@google.com
9913207Sgabeblack@google.com        ::sc_core::sc_interface *interface;
10013207Sgabeblack@google.com        ::sc_core::sc_port_base *port;
10113207Sgabeblack@google.com    };
10213207Sgabeblack@google.com
10313207Sgabeblack@google.com    struct Sensitivity
10413207Sgabeblack@google.com    {
10513207Sgabeblack@google.com        Sensitivity(StaticSensitivityPort *port) :
10613288Sgabeblack@google.com            port(port), finder(nullptr)
10713207Sgabeblack@google.com        {}
10813207Sgabeblack@google.com
10913207Sgabeblack@google.com        Sensitivity(StaticSensitivityFinder *finder) :
11013288Sgabeblack@google.com            port(nullptr), finder(finder)
11113207Sgabeblack@google.com        {}
11213207Sgabeblack@google.com
11313207Sgabeblack@google.com        StaticSensitivityPort *port;
11413207Sgabeblack@google.com        StaticSensitivityFinder *finder;
11513207Sgabeblack@google.com    };
11613207Sgabeblack@google.com
11713207Sgabeblack@google.com    std::vector<Binding *> bindings;
11813207Sgabeblack@google.com    std::vector<Sensitivity *> sensitivities;
11913288Sgabeblack@google.com    std::vector<Reset *> resets;
12013207Sgabeblack@google.com
12113207Sgabeblack@google.com  public:
12213207Sgabeblack@google.com    static Port *
12313207Sgabeblack@google.com    fromPort(const ::sc_core::sc_port_base *pb)
12413207Sgabeblack@google.com    {
12513207Sgabeblack@google.com        return pb->_gem5Port;
12613207Sgabeblack@google.com    }
12713207Sgabeblack@google.com
12813207Sgabeblack@google.com    ::sc_core::sc_port_base *sc_port_base() { return portBase; }
12913207Sgabeblack@google.com
13013207Sgabeblack@google.com    Port(::sc_core::sc_port_base *port_base, int max) :
13113273Sgabeblack@google.com        portBase(port_base), finalized(false), _maxSize(max), _size(0),
13213273Sgabeblack@google.com        regPortNeeded(true)
13313207Sgabeblack@google.com    {
13413207Sgabeblack@google.com        allPorts.push_front(this);
13513207Sgabeblack@google.com    }
13613207Sgabeblack@google.com
13713282Sgabeblack@google.com    ~Port() { allPorts.remove(this); }
13813282Sgabeblack@google.com
13913207Sgabeblack@google.com    void
14013207Sgabeblack@google.com    bind(::sc_core::sc_interface *interface)
14113207Sgabeblack@google.com    {
14213270Sgabeblack@google.com        if (bindings.empty())
14313270Sgabeblack@google.com            addInterface(interface);
14413270Sgabeblack@google.com        else
14513270Sgabeblack@google.com            bindings.push_back(new Binding(interface));
14613207Sgabeblack@google.com    }
14713207Sgabeblack@google.com
14813207Sgabeblack@google.com    void
14913207Sgabeblack@google.com    bind(::sc_core::sc_port_base *port)
15013207Sgabeblack@google.com    {
15113207Sgabeblack@google.com        bindings.push_back(new Binding(port));
15213207Sgabeblack@google.com    }
15313207Sgabeblack@google.com
15413207Sgabeblack@google.com    void sensitive(StaticSensitivityPort *port);
15513207Sgabeblack@google.com    void sensitive(StaticSensitivityFinder *finder);
15613288Sgabeblack@google.com    void addReset(Reset *reset);
15713207Sgabeblack@google.com
15813207Sgabeblack@google.com    void finalize();
15913273Sgabeblack@google.com    void regPort();
16013207Sgabeblack@google.com
16113207Sgabeblack@google.com    int size() { return _size; }
16213319Sgabeblack@google.com    int maxSize() { return _maxSize ? _maxSize : _size; }
16313207Sgabeblack@google.com};
16413207Sgabeblack@google.com
16513207Sgabeblack@google.com} // namespace sc_gem5
16613207Sgabeblack@google.com
16713207Sgabeblack@google.com#endif // __SYSTEMC_CORE_PORT_HH__
168