gem5 v24.0.0.0
Loading...
Searching...
No Matches
NetworkBridge.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Advanced Micro Devices, Inc.
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 met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32
34
35#include <cmath>
36
37#include "debug/RubyNetwork.hh"
38#include "params/GarnetIntLink.hh"
39
40namespace gem5
41{
42
43namespace ruby
44{
45
46namespace garnet
47{
48
51{
52 enCdc = true;
53 enSerDes = true;
54 mType = p.vtype;
55
56 cdcLatency = p.cdc_latency;
57 serDesLatency = p.serdes_latency;
59
60 nLink = p.link;
61 if (mType == enums::LINK_OBJECT) {
64 } else if (mType == enums::OBJECT_LINK) {
67 } else {
68 // CDC type must be set
69 panic("CDC type must be set");
70 }
71}
72
73void
74NetworkBridge::setVcsPerVnet(uint32_t consumerVcs)
75{
76 DPRINTF(RubyNetwork, "VcsPerVnet VC: %d\n", consumerVcs);
77 NetworkLink::setVcsPerVnet(consumerVcs);
78 lenBuffer.resize(consumerVcs * m_virt_nets);
79 sizeSent.resize(consumerVcs * m_virt_nets);
80 flitsSent.resize(consumerVcs * m_virt_nets);
81 extraCredit.resize(consumerVcs * m_virt_nets);
82
83 nLink->setVcsPerVnet(consumerVcs);
84}
85
86void
87NetworkBridge::initBridge(NetworkBridge *coBrid, bool cdc_en, bool serdes_en)
88{
89 coBridge = coBrid;
90 enCdc = cdc_en;
91 enSerDes = serdes_en;
92}
93
97
98void
100{
101 Cycles totLatency = latency;
102
103 if (enCdc) {
104 // Add the CDC latency
105 totLatency = latency + cdcLatency;
106 }
107
108 Tick sendTime = link_consumer->getObject()->clockEdge(totLatency);
109 Tick nextAvailTick = lastScheduledAt + link_consumer->getObject()->\
110 cyclesToTicks(Cycles(1));
111 sendTime = std::max(nextAvailTick, sendTime);
112 t_flit->set_time(sendTime);
113 lastScheduledAt = sendTime;
114 linkBuffer.insert(t_flit);
116}
117
118void
119NetworkBridge::neutralize(int vc, int eCredit)
120{
121 extraCredit[vc].push(eCredit);
122}
123
124void
126{
127 // Serialize-Deserialize only if it is enabled
128 if (enSerDes) {
129 // Calculate the target-width
130 int target_width = bitWidth;
131 int cur_width = nLink->bitWidth;
132 if (mType == enums::OBJECT_LINK) {
133 target_width = nLink->bitWidth;
134 cur_width = bitWidth;
135 }
136
137 DPRINTF(RubyNetwork, "Target width: %d Current: %d\n",
138 target_width, cur_width);
139 assert(target_width != cur_width);
140
141 int vc = t_flit->get_vc();
142
143 if (target_width > cur_width) {
144 // Deserialize
145 // This deserializer combines flits from the
146 // same message together
147 int num_flits = 0;
148 int flitPossible = 0;
149 if (t_flit->get_type() == CREDIT_) {
150 lenBuffer[vc]++;
151 assert(extraCredit[vc].front());
152 if (lenBuffer[vc] == extraCredit[vc].front()) {
153 flitPossible = 1;
154 extraCredit[vc].pop();
155 lenBuffer[vc] = 0;
156 }
157 } else if (t_flit->get_type() == TAIL_ ||
158 t_flit->get_type() == HEAD_TAIL_) {
159 // If its the end of packet, then send whatever
160 // is available.
161 int sizeAvail = (t_flit->msgSize - sizeSent[vc]);
162 flitPossible = ceil((float)sizeAvail/(float)target_width);
163 assert (flitPossible < 2);
164 num_flits = (t_flit->get_id() + 1) - flitsSent[vc];
165 // Stop tracking the packet.
166 flitsSent[vc] = 0;
167 sizeSent[vc] = 0;
168 } else {
169 // If we are yet to receive the complete packet
170 // track the size recieved and flits deserialized.
171 int sizeAvail =
172 ((t_flit->get_id() + 1)*cur_width) - sizeSent[vc];
173 flitPossible = floor((float)sizeAvail/(float)target_width);
174 assert (flitPossible < 2);
175 num_flits = (t_flit->get_id() + 1) - flitsSent[vc];
176 if (flitPossible) {
177 sizeSent[vc] += target_width;
178 flitsSent[vc] = t_flit->get_id() + 1;
179 }
180 }
181
182 DPRINTF(RubyNetwork, "Deserialize :%dB -----> %dB "
183 " vc:%d\n", cur_width, target_width, vc);
184
185 flit *fl = NULL;
186 if (flitPossible) {
187 fl = t_flit->deserialize(lenBuffer[vc], num_flits,
188 target_width);
189 }
190
191 // Inform the credit serializer about the number
192 // of flits that were generated.
193 if (t_flit->get_type() != CREDIT_ && fl) {
194 coBridge->neutralize(vc, num_flits);
195 }
196
197 // Schedule only if we are done deserializing
198 if (fl) {
199 DPRINTF(RubyNetwork, "Scheduling a flit\n");
200 lenBuffer[vc] = 0;
202 }
203 // Delete this flit, new flit is sent in any case
204 delete t_flit;
205 } else {
206 // Serialize
207 DPRINTF(RubyNetwork, "Serializing flit :%d -----> %d "
208 "(vc:%d, Original Message Size: %d)\n",
209 cur_width, target_width, vc, t_flit->msgSize);
210
211 int flitPossible = 0;
212 if (t_flit->get_type() == CREDIT_) {
213 // We store the deserialization ratio and then
214 // access it when serializing credits in the
215 // oppposite direction.
216 assert(extraCredit[vc].front());
217 flitPossible = extraCredit[vc].front();
218 extraCredit[vc].pop();
219 } else if (t_flit->get_type() == HEAD_ ||
220 t_flit->get_type() == BODY_) {
221 int sizeAvail =
222 ((t_flit->get_id() + 1)*cur_width) - sizeSent[vc];
223 flitPossible = floor((float)sizeAvail/(float)target_width);
224 if (flitPossible) {
225 sizeSent[vc] += flitPossible*target_width;
226 flitsSent[vc] += flitPossible;
227 }
228 } else {
229 int sizeAvail = t_flit->msgSize - sizeSent[vc];
230 flitPossible = ceil((float)sizeAvail/(float)target_width);
231 sizeSent[vc] = 0;
232 flitsSent[vc] = 0;
233 }
234 assert(flitPossible > 0);
235
236 // Schedule all the flits
237 // num_flits could be zero for credits
238 for (int i = 0; i < flitPossible; i++) {
239 // Ignore neutralized credits
240 flit *fl = t_flit->serialize(i, flitPossible, target_width);
242 DPRINTF(RubyNetwork, "Serialized to flit[%d of %d parts]:"
243 " %s\n", i+1, flitPossible, *fl);
244 }
245
246 if (t_flit->get_type() != CREDIT_) {
247 coBridge->neutralize(vc, flitPossible);
248 }
249 // Delete this flit, new flit is sent in any case
250 delete t_flit;
251 }
252 return;
253 }
254
255 // If only CDC is enabled schedule it
256 scheduleFlit(t_flit, Cycles(0));
257}
258void
260{
261 flit *t_flit;
262
263 if (link_srcQueue->isReady(curTick())) {
264 t_flit = link_srcQueue->getTopFlit();
265 DPRINTF(RubyNetwork, "Recieved flit %s\n", *t_flit);
266 flitisizeAndSend(t_flit);
267 }
268
269 // Reschedule in case there is a waiting flit.
270 if (!link_srcQueue->isEmpty()) {
272 }
273}
274
275} // namespace garnet
276} // namespace ruby
277} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Cycles is a wrapper class for representing cycle counts, i.e.
Definition types.hh:79
void scheduleEventAbsolute(Tick timeAbs)
Definition Consumer.cc:63
void scheduleEvent(Cycles timeDelta)
Definition Consumer.cc:56
ClockedObject * getObject()
Definition Consumer.hh:82
void setVcsPerVnet(uint32_t consumerVcs)
std::vector< std::queue< int > > extraCredit
void scheduleFlit(flit *t_flit, Cycles latency)
void neutralize(int vc, int eCredit)
void initBridge(NetworkBridge *coBrid, bool cdc_en, bool serdes_en)
bool isReady(Tick curTime)
Definition flitBuffer.cc:60
void set_time(Tick time)
Definition flit.hh:75
virtual flit * serialize(int ser_id, int parts, uint32_t bWidth)
Definition flit.cc:77
virtual flit * deserialize(int des_id, int num_flits, uint32_t bWidth)
Definition flit.cc:94
flit_type get_type()
Definition flit.hh:70
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 0 > p
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
uint64_t Tick
Tick count type.
Definition types.hh:58

Generated on Tue Jun 18 2024 16:24:05 for gem5 by doxygen 1.11.0