misc: SystemC Elastic Trace Player Example.
[gem5.git] / util / tlm / sc_port.hh
1 /*
2 * Copyright (c) 2015, University of Kaiserslautern
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * 3. Neither the name of the copyright holder nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
24 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * Authors: Matthias Jung
33 */
34
35 #ifndef __SIM_SC_TRANSACTOR_HH__
36 #define __SIM_SC_TRANSACTOR_HH__
37
38 #include <tlm_utils/simple_initiator_socket.h>
39
40 #include <map>
41 #include <systemc>
42 #include <tlm>
43
44 #include "mem/external_slave.hh"
45 #include "sc_mm.hh"
46 #include "sc_module.hh"
47
48 namespace Gem5SystemC
49 {
50 /**
51 * Test that gem5 is at the same time as SystemC
52 */
53 #define CAUGHT_UP do { \
54 assert(curTick() == sc_core::sc_time_stamp().value()); \
55 } while (0)
56
57
58 class sc_transactor : public tlm::tlm_initiator_socket<>,
59 public tlm::tlm_bw_transport_if<>,
60 public ExternalSlave::Port
61 {
62 public:
63 sc_transactor &iSocket;
64
65 /**
66 * A 'Fake Payload Event Queue', similar to the TLM PEQs. This will help
67 * that gem5 behaves like a normal TLM Initiator
68 */
69 template<typename OWNER>
70 class payloadEvent : public Event
71 {
72 public:
73 OWNER &port;
74 const std::string eventName;
75 void (OWNER::* handler)(payloadEvent<OWNER> * pe,
76 tlm::tlm_generic_payload& trans,
77 const tlm::tlm_phase &phase);
78
79 protected:
80 tlm::tlm_generic_payload *t;
81 tlm::tlm_phase p;
82
83 void process() { (port.*handler)(this,*t, p); }
84
85 public:
86 const std::string name() const { return eventName; }
87
88 payloadEvent(
89 OWNER &port_,
90 void (OWNER::* handler_)(payloadEvent<OWNER> * pe,
91 tlm::tlm_generic_payload& trans,
92 const tlm::tlm_phase &phase),
93 const std::string &event_name) :
94 port(port_),
95 eventName(event_name),
96 handler(handler_)
97 { }
98
99 /// Schedule an event into gem5
100 void
101 notify(tlm::tlm_generic_payload& trans,
102 const tlm::tlm_phase &phase,
103 const sc_core::sc_time& delay)
104 {
105 assert(!scheduled());
106
107 t = &trans;
108 p = phase;
109
110 /**
111 * Get time from SystemC as this will alway be more up to date
112 * than gem5's
113 */
114 Tick nextEventTick = sc_core::sc_time_stamp().value()
115 + delay.value();
116
117 port.owner.wakeupEventQueue(nextEventTick);
118 port.owner.schedule(this, nextEventTick);
119 }
120 };
121
122 /** One instance of pe and the related callback needed */
123 //payloadEvent<sc_transactor> pe;
124 void pec(payloadEvent<sc_transactor> * pe,
125 tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase);
126
127 /**
128 * A transaction after BEGIN_REQ has been sent but before END_REQ, which
129 * is blocking the request channel (Exlusion Rule, see IEEE1666)
130 */
131 tlm::tlm_generic_payload *blockingRequest;
132
133 /**
134 * Did another gem5 request arrive while currently blocked?
135 * This variable is needed when a retry should happen
136 */
137 bool needToSendRequestRetry;
138
139 /**
140 * A response which has been asked to retry by gem5 and so is blocking
141 * the response channel
142 */
143 tlm::tlm_generic_payload *blockingResponse;
144
145 protected:
146 /** The gem5 Port slave interface */
147 Tick recvAtomic(PacketPtr packet);
148 void recvFunctional(PacketPtr packet);
149 bool recvTimingReq(PacketPtr packet);
150 bool recvTimingSnoopResp(PacketPtr packet);
151 void recvRespRetry();
152 void recvFunctionalSnoop(PacketPtr packet);
153
154 /** The TLM initiator interface */
155 tlm::tlm_sync_enum nb_transport_bw(tlm::tlm_generic_payload& trans,
156 tlm::tlm_phase& phase,
157 sc_core::sc_time& t);
158
159 void invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
160 sc_dt::uint64 end_range);
161
162 public:
163 sc_transactor(const std::string &name_,
164 const std::string &systemc_name,
165 ExternalSlave &owner_);
166 };
167
168 void registerPort(const std::string &name, Port &port);
169
170 void registerSCPorts();
171
172 }
173
174 #endif // __SIM_SC_PORT_HH__