port.hh revision 13239:0fe49a9e1754
1/*
2 * Copyright 2018 Google, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution;
11 * neither the name of the copyright holders nor the names of its
12 * contributors may be used to endorse or promote products derived from
13 * this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * Authors: Gabe Black
28 */
29
30#ifndef __SYSTEMC_CORE_PORT_HH__
31#define __SYSTEMC_CORE_PORT_HH__
32
33#include <list>
34#include <vector>
35
36#include "base/cprintf.hh"
37#include "systemc/ext/core/sc_interface.hh"
38#include "systemc/ext/core/sc_port.hh"
39
40namespace sc_gem5
41{
42
43class StaticSensitivityPort;
44class StaticSensitivityFinder;
45
46class Port;
47
48extern std::list<Port *> allPorts;
49
50class Port
51{
52  private:
53    ::sc_core::sc_port_base *portBase;
54
55    bool finalized;
56    int _maxSize;
57    int _size;
58
59    void finalizePort(StaticSensitivityPort *port);
60    void finalizeFinder(StaticSensitivityFinder *finder);
61
62    void
63    addInterface(::sc_core::sc_interface *iface)
64    {
65        for (int i = 0; i < _size; i++) {
66            if (getInterface(i) == iface) {
67                std::string msg =
68                    csprintf("interface already bound to port: port '%s' (%s)",
69                        portBase->name(), portBase->kind());
70                SC_REPORT_ERROR("(E107) bind interface to port failed",
71                        msg.c_str());
72            }
73        }
74        _size++;
75        portBase->_gem5AddInterface(iface);
76    }
77
78    void
79    addInterfaces(::sc_core::sc_port_base *pb)
80    {
81        for (int i = 0; i < pb->size(); i++)
82            addInterface(pb->_gem5Interface(i));
83    }
84
85    ::sc_core::sc_interface *
86    getInterface(int i)
87    {
88        return portBase->_gem5Interface(i);
89    }
90
91    struct Binding
92    {
93        explicit Binding(::sc_core::sc_interface *interface) :
94            interface(interface), port(nullptr)
95        {}
96
97        explicit Binding(::sc_core::sc_port_base *port) :
98            interface(nullptr), port(port)
99        {}
100
101        ::sc_core::sc_interface *interface;
102        ::sc_core::sc_port_base *port;
103    };
104
105    struct Sensitivity
106    {
107        Sensitivity(StaticSensitivityPort *port) :
108            port(port), finder(nullptr)
109        {}
110
111        Sensitivity(StaticSensitivityFinder *finder) :
112            port(nullptr), finder(finder)
113        {}
114
115        StaticSensitivityPort *port;
116        StaticSensitivityFinder *finder;
117    };
118
119    std::vector<Binding *> bindings;
120    std::vector<Sensitivity *> sensitivities;
121
122  public:
123    static Port *
124    fromPort(const ::sc_core::sc_port_base *pb)
125    {
126        return pb->_gem5Port;
127    }
128
129    ::sc_core::sc_port_base *sc_port_base() { return portBase; }
130
131    Port(::sc_core::sc_port_base *port_base, int max) :
132        portBase(port_base), finalized(false), _maxSize(max), _size(0)
133    {
134        allPorts.push_front(this);
135    }
136
137    void
138    bind(::sc_core::sc_interface *interface)
139    {
140        bindings.push_back(new Binding(interface));
141    }
142
143    void
144    bind(::sc_core::sc_port_base *port)
145    {
146        bindings.push_back(new Binding(port));
147    }
148
149    void sensitive(StaticSensitivityPort *port);
150    void sensitive(StaticSensitivityFinder *finder);
151
152    void finalize();
153
154    int size() { return _size; }
155    int maxSize() { return _maxSize; }
156};
157
158} // namespace sc_gem5
159
160#endif // __SYSTEMC_CORE_PORT_HH__
161