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

Generated on Wed Sep 30 2020 14:02:13 for gem5 by doxygen 1.8.17