gem5  v21.0.1.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 
34 
36 
37 #include <cmath>
38 
39 #include "debug/RubyNetwork.hh"
40 #include "params/GarnetIntLink.hh"
41 
43  :CreditLink(p)
44 {
45  enCdc = true;
46  enSerDes = true;
47  mType = p.vtype;
48 
49  cdcLatency = p.cdc_latency;
50  serDesLatency = p.serdes_latency;
51  lastScheduledAt = 0;
52 
53  nLink = p.link;
54  if (mType == Enums::LINK_OBJECT) {
55  nLink->setLinkConsumer(this);
57  } else if (mType == Enums::OBJECT_LINK) {
60  } else {
61  // CDC type must be set
62  panic("CDC type must be set");
63  }
64 }
65 
66 void
67 NetworkBridge::setVcsPerVnet(uint32_t consumerVcs)
68 {
69  DPRINTF(RubyNetwork, "VcsPerVnet VC: %d\n", consumerVcs);
70  NetworkLink::setVcsPerVnet(consumerVcs);
71  lenBuffer.resize(consumerVcs * m_virt_nets);
72  sizeSent.resize(consumerVcs * m_virt_nets);
73  flitsSent.resize(consumerVcs * m_virt_nets);
74  extraCredit.resize(consumerVcs * m_virt_nets);
75 
76  nLink->setVcsPerVnet(consumerVcs);
77 }
78 
79 void
80 NetworkBridge::initBridge(NetworkBridge *coBrid, bool cdc_en, bool serdes_en)
81 {
82  coBridge = coBrid;
83  enCdc = cdc_en;
84  enSerDes = serdes_en;
85 }
86 
88 {
89 }
90 
91 void
93 {
94  Cycles totLatency = latency;
95 
96  if (enCdc) {
97  // Add the CDC latency
98  totLatency = latency + cdcLatency;
99  }
100 
101  Tick sendTime = link_consumer->getObject()->clockEdge(totLatency);
102  Tick nextAvailTick = lastScheduledAt + link_consumer->getObject()->\ cyclesToTicks(Cycles(1));
103  sendTime = std::max(nextAvailTick, sendTime);
104  t_flit->set_time(sendTime);
105  lastScheduledAt = sendTime;
106  linkBuffer.insert(t_flit);
108 }
109 
110 void
111 NetworkBridge::neutralize(int vc, int eCredit)
112 {
113  extraCredit[vc].push(eCredit);
114 }
115 
116 void
118 {
119  // Serialize-Deserialize only if it is enabled
120  if (enSerDes) {
121  // Calculate the target-width
122  int target_width = bitWidth;
123  int cur_width = nLink->bitWidth;
124  if (mType == Enums::OBJECT_LINK) {
125  target_width = nLink->bitWidth;
126  cur_width = bitWidth;
127  }
128 
129  DPRINTF(RubyNetwork, "Target width: %d Current: %d\n",
130  target_width, cur_width);
131  assert(target_width != cur_width);
132 
133  int vc = t_flit->get_vc();
134 
135  if (target_width > cur_width) {
136  // Deserialize
137  // This deserializer combines flits from the
138  // same message together
139  int num_flits = 0;
140  int flitPossible = 0;
141  if (t_flit->get_type() == CREDIT_) {
142  lenBuffer[vc]++;
143  assert(extraCredit[vc].front());
144  if (lenBuffer[vc] == extraCredit[vc].front()) {
145  flitPossible = 1;
146  extraCredit[vc].pop();
147  lenBuffer[vc] = 0;
148  }
149  } else if (t_flit->get_type() == TAIL_ ||
150  t_flit->get_type() == HEAD_TAIL_) {
151  // If its the end of packet, then send whatever
152  // is available.
153  int sizeAvail = (t_flit->msgSize - sizeSent[vc]);
154  flitPossible = ceil((float)sizeAvail/(float)target_width);
155  assert (flitPossible < 2);
156  num_flits = (t_flit->get_id() + 1) - flitsSent[vc];
157  // Stop tracking the packet.
158  flitsSent[vc] = 0;
159  sizeSent[vc] = 0;
160  } else {
161  // If we are yet to receive the complete packet
162  // track the size recieved and flits deserialized.
163  int sizeAvail =
164  ((t_flit->get_id() + 1)*cur_width) - sizeSent[vc];
165  flitPossible = floor((float)sizeAvail/(float)target_width);
166  assert (flitPossible < 2);
167  num_flits = (t_flit->get_id() + 1) - flitsSent[vc];
168  if (flitPossible) {
169  sizeSent[vc] += target_width;
170  flitsSent[vc] = t_flit->get_id() + 1;
171  }
172  }
173 
174  DPRINTF(RubyNetwork, "Deserialize :%dB -----> %dB "
175  " vc:%d\n", cur_width, target_width, vc);
176 
177  flit *fl = NULL;
178  if (flitPossible) {
179  fl = t_flit->deserialize(lenBuffer[vc], num_flits,
180  target_width);
181  }
182 
183  // Inform the credit serializer about the number
184  // of flits that were generated.
185  if (t_flit->get_type() != CREDIT_ && fl) {
186  coBridge->neutralize(vc, num_flits);
187  }
188 
189  // Schedule only if we are done deserializing
190  if (fl) {
191  DPRINTF(RubyNetwork, "Scheduling a flit\n");
192  lenBuffer[vc] = 0;
194  }
195  // Delete this flit, new flit is sent in any case
196  delete t_flit;
197  } else {
198  // Serialize
199  DPRINTF(RubyNetwork, "Serializing flit :%d -----> %d "
200  "(vc:%d, Original Message Size: %d)\n",
201  cur_width, target_width, vc, t_flit->msgSize);
202 
203  int flitPossible = 0;
204  if (t_flit->get_type() == CREDIT_) {
205  // We store the deserialization ratio and then
206  // access it when serializing credits in the
207  // oppposite direction.
208  assert(extraCredit[vc].front());
209  flitPossible = extraCredit[vc].front();
210  extraCredit[vc].pop();
211  } else if (t_flit->get_type() == HEAD_ ||
212  t_flit->get_type() == BODY_) {
213  int sizeAvail =
214  ((t_flit->get_id() + 1)*cur_width) - sizeSent[vc];
215  flitPossible = floor((float)sizeAvail/(float)target_width);
216  if (flitPossible) {
217  sizeSent[vc] += flitPossible*target_width;
218  flitsSent[vc] += flitPossible;
219  }
220  } else {
221  int sizeAvail = t_flit->msgSize - sizeSent[vc];
222  flitPossible = ceil((float)sizeAvail/(float)target_width);
223  sizeSent[vc] = 0;
224  flitsSent[vc] = 0;
225  }
226  assert(flitPossible > 0);
227 
228  // Schedule all the flits
229  // num_flits could be zero for credits
230  for (int i = 0; i < flitPossible; i++) {
231  // Ignore neutralized credits
232  flit *fl = t_flit->serialize(i, flitPossible, target_width);
234  DPRINTF(RubyNetwork, "Serialized to flit[%d of %d parts]:"
235  " %s\n", i+1, flitPossible, *fl);
236  }
237 
238  if (t_flit->get_type() != CREDIT_) {
239  coBridge->neutralize(vc, flitPossible);
240  }
241  // Delete this flit, new flit is sent in any case
242  delete t_flit;
243  }
244  return;
245  }
246 
247  // If only CDC is enabled schedule it
248  scheduleFlit(t_flit, Cycles(0));
249 }
250 void
252 {
253  flit *t_flit;
254 
255  if (link_srcQueue->isReady(curTick())) {
256  t_flit = link_srcQueue->getTopFlit();
257  DPRINTF(RubyNetwork, "Recieved flit %s\n", *t_flit);
258  flitisizeAndSend(t_flit);
259  return;
260  }
261  assert(!link_srcQueue->getSize());
262 }
263 
NetworkBridge::wakeup
void wakeup()
Definition: NetworkBridge.cc:252
NetworkBridge::coBridge
NetworkBridge * coBridge
Definition: NetworkBridge.hh:70
flit
Definition: flit.hh:41
NetworkBridge::lastScheduledAt
Tick lastScheduledAt
Definition: NetworkBridge.hh:88
NetworkBridge::nLink
NetworkLink * nLink
Definition: NetworkBridge.hh:75
NetworkBridge::sizeSent
std::vector< int > sizeSent
Definition: NetworkBridge.hh:92
NetworkBridge::lenBuffer
std::vector< int > lenBuffer
Definition: NetworkBridge.hh:91
NetworkBridge::flitisizeAndSend
void flitisizeAndSend(flit *t_flit)
Definition: NetworkBridge.cc:118
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:59
NetworkBridge::setVcsPerVnet
void setVcsPerVnet(uint32_t consumerVcs)
Definition: NetworkBridge.cc:67
NetworkBridge::enCdc
bool enCdc
Definition: NetworkBridge.hh:78
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:80
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
NetworkBridge::flitsSent
std::vector< int > flitsSent
Definition: NetworkBridge.hh:93
flitBuffer::getSize
int getSize() const
Definition: flitBuffer.hh:52
NetworkBridge.hh
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:83
NetworkBridge::extraCredit
std::vector< std::queue< int > > extraCredit
Definition: NetworkBridge.hh:94
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:112
BODY_
@ BODY_
Definition: CommonTypes.hh:38
NetworkBridge
Definition: NetworkBridge.hh:51
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:80
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:57
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:79
HEAD_TAIL_
@ HEAD_TAIL_
Definition: CommonTypes.hh:38
NetworkBridge::~NetworkBridge
~NetworkBridge()
Definition: NetworkBridge.cc:87
curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:43
NetworkBridge::NetworkBridge
NetworkBridge(const Params &p)
Definition: NetworkBridge.cc:42
Consumer::getObject
ClockedObject * getObject()
Definition: Consumer.hh:75
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
NetworkBridge::cdcLatency
Cycles cdcLatency
Definition: NetworkBridge.hh:85
flit::serialize
virtual flit * serialize(int ser_id, int parts, uint32_t bWidth)
Definition: flit.cc:67
NetworkBridge::serDesLatency
Cycles serDesLatency
Definition: NetworkBridge.hh:86
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
NetworkBridge::scheduleFlit
void scheduleFlit(flit *t_flit, Cycles latency)
Definition: NetworkBridge.cc:92

Generated on Tue Jun 22 2021 15:28:29 for gem5 by doxygen 1.8.17