misc: Delete the now unnecessary create methods.
[gem5.git] / src / mem / mem_delay.cc
1 /*
2 * Copyright (c) 2018, 2020 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38 #include "mem/mem_delay.hh"
39
40 #include "params/MemDelay.hh"
41 #include "params/SimpleMemDelay.hh"
42
43 MemDelay::MemDelay(const MemDelayParams &p)
44 : ClockedObject(p),
45 requestPort(name() + "-mem_side_port", *this),
46 responsePort(name() + "-cpu_side_port", *this),
47 reqQueue(*this, requestPort),
48 respQueue(*this, responsePort),
49 snoopRespQueue(*this, requestPort)
50 {
51 }
52
53 void
54 MemDelay::init()
55 {
56 if (!responsePort.isConnected() || !requestPort.isConnected())
57 fatal("Memory delay is not connected on both sides.\n");
58 }
59
60
61 Port &
62 MemDelay::getPort(const std::string &if_name, PortID idx)
63 {
64 if (if_name == "mem_side_port") {
65 return requestPort;
66 } else if (if_name == "cpu_side_port") {
67 return responsePort;
68 } else {
69 return ClockedObject::getPort(if_name, idx);
70 }
71 }
72
73 bool
74 MemDelay::trySatisfyFunctional(PacketPtr pkt)
75 {
76 return responsePort.trySatisfyFunctional(pkt) ||
77 requestPort.trySatisfyFunctional(pkt);
78 }
79
80 MemDelay::RequestPort::RequestPort(const std::string &_name, MemDelay &_parent)
81 : QueuedRequestPort(_name, &_parent,
82 _parent.reqQueue, _parent.snoopRespQueue),
83 parent(_parent)
84 {
85 }
86
87 bool
88 MemDelay::RequestPort::recvTimingResp(PacketPtr pkt)
89 {
90 // technically the packet only reaches us after the header delay,
91 // and typically we also need to deserialise any payload
92 const Tick receive_delay = pkt->headerDelay + pkt->payloadDelay;
93 pkt->headerDelay = pkt->payloadDelay = 0;
94
95 const Tick when = curTick() + parent.delayResp(pkt) + receive_delay;
96
97 parent.responsePort.schedTimingResp(pkt, when);
98
99 return true;
100 }
101
102 void
103 MemDelay::RequestPort::recvFunctionalSnoop(PacketPtr pkt)
104 {
105 if (parent.trySatisfyFunctional(pkt)) {
106 pkt->makeResponse();
107 } else {
108 parent.responsePort.sendFunctionalSnoop(pkt);
109 }
110 }
111
112 Tick
113 MemDelay::RequestPort::recvAtomicSnoop(PacketPtr pkt)
114 {
115 const Tick delay = parent.delaySnoopResp(pkt);
116
117 return delay + parent.responsePort.sendAtomicSnoop(pkt);
118 }
119
120 void
121 MemDelay::RequestPort::recvTimingSnoopReq(PacketPtr pkt)
122 {
123 parent.responsePort.sendTimingSnoopReq(pkt);
124 }
125
126
127 MemDelay::ResponsePort::
128 ResponsePort(const std::string &_name, MemDelay &_parent)
129 : QueuedResponsePort(_name, &_parent, _parent.respQueue),
130 parent(_parent)
131 {
132 }
133
134 Tick
135 MemDelay::ResponsePort::recvAtomic(PacketPtr pkt)
136 {
137 const Tick delay = parent.delayReq(pkt) + parent.delayResp(pkt);
138
139 return delay + parent.requestPort.sendAtomic(pkt);
140 }
141
142 bool
143 MemDelay::ResponsePort::recvTimingReq(PacketPtr pkt)
144 {
145 // technically the packet only reaches us after the header
146 // delay, and typically we also need to deserialise any
147 // payload
148 Tick receive_delay = pkt->headerDelay + pkt->payloadDelay;
149 pkt->headerDelay = pkt->payloadDelay = 0;
150
151 const Tick when = curTick() + parent.delayReq(pkt) + receive_delay;
152
153 parent.requestPort.schedTimingReq(pkt, when);
154
155 return true;
156 }
157
158 void
159 MemDelay::ResponsePort::recvFunctional(PacketPtr pkt)
160 {
161 if (parent.trySatisfyFunctional(pkt)) {
162 pkt->makeResponse();
163 } else {
164 parent.requestPort.sendFunctional(pkt);
165 }
166 }
167
168 bool
169 MemDelay::ResponsePort::recvTimingSnoopResp(PacketPtr pkt)
170 {
171 const Tick when = curTick() + parent.delaySnoopResp(pkt);
172
173 parent.requestPort.schedTimingSnoopResp(pkt, when);
174
175 return true;
176 }
177
178
179
180 SimpleMemDelay::SimpleMemDelay(const SimpleMemDelayParams &p)
181 : MemDelay(p),
182 readReqDelay(p.read_req),
183 readRespDelay(p.read_resp),
184 writeReqDelay(p.write_req),
185 writeRespDelay(p.write_resp)
186 {
187 }
188
189 Tick
190 SimpleMemDelay::delayReq(PacketPtr pkt)
191 {
192 if (pkt->isRead()) {
193 return readReqDelay;
194 } else if (pkt->isWrite()) {
195 return writeReqDelay;
196 } else {
197 return 0;
198 }
199 }
200
201 Tick
202 SimpleMemDelay::delayResp(PacketPtr pkt)
203 {
204 if (pkt->isRead()) {
205 return readRespDelay;
206 } else if (pkt->isWrite()) {
207 return writeRespDelay;
208 } else {
209 return 0;
210 }
211 }